Python try except lambda 内的块

问题描述 投票:0回答:5

是否可以在 lambda 函数内部使用 try except 块?我需要 lambda 函数将某个变量转换为整数,但并非所有值都能够转换为整数。

python lambda try-except
5个回答
113
投票

不。 Python lambda 只能是单个表达式。使用命名函数。

编写一个通用函数来转换类型很方便:

def tryconvert(value, default, *types):
    for t in types:
        try:
            return t(value)
        except (ValueError, TypeError):
            continue
    return default

然后你可以写你的 lambda:

lambda v: tryconvert(v, 0, int)

您还可以编写

tryconvert()
,以便它返回一个接受要转换的值的函数;那么你不需要 lambda:

def tryconvert(default, *types):
    def convert(value):
        for t in types:
            try:
                return t(value)
            except (ValueError, TypeError):
                continue
        return default
    # set name of conversion function to something more useful
    namext = ("_%s_" % default) + "_".join(t.__name__ for t in types)
    if hasattr(convert, "__qualname__"): convert.__qualname__ += namext
    convert.__name__ += namext
    return convert

现在

tryconvert(0, int)
返回一个函数
convert_0_int
,它接受一个值并将其转换为整数,如果无法完成,则返回
0
。您可以立即使用此功能(不保存副本):

mynumber = tryconert(0, int)(value)

或保存以供稍后调用:

intconvert = tryconvert(0, int)
# later...
mynumber = intconvert(value)

41
投票

在这个特定实例中,您可以避免使用像这样的

try
块:

lambda s: int(s) if s.isdigit() else 0

如果 isdigit()

 的字符都是数字,则 
s 字符串方法 返回 true。 (如果您需要接受负数,则必须进行一些额外的检查。)
    


8
投票

我将这段小代码放在一起,以演示捕获异常并在 lambda 内对异常做出反应的可能性。它相当初级,或多或少可以作为概念证明。

示例

>>> print_msg = lambda msg, **print_kwargs: \ ... begin( ... print, msg, end='... ', **print_kwargs ... ).\ ... rescue( ... (TypeError, AttributeError), ... lambda exc: print(f'just caught "{exc}"! how fun!') ... ).\ ... ensure(print, 'ok done.')() >>> print_msg('check') check... ok done. >>> print_msg('check', file=1) just caught "'int' object has no attribute 'write'"! how fun! ok done. >>> print_msg('check', sep=1) just caught "sep must be None or a string, not int"! how fun! ok done.

更实际的例子

modules = filter(None, ( begin(importlib.import_module, modname).rescue(lambda exc: None)() for modname in module_names ))


代码

from typing import Iterable class begin: def __init__(self, fun, *args, **kwargs): self.fun = fun self.args = args self.kwargs = kwargs self.exception_types_and_handlers = [] self.finalize = None def rescue(self, exception_types, handler): if not isinstance(exception_types, Iterable): exception_types = (exception_types,) self.exception_types_and_handlers.append((exception_types, handler)) return self def ensure(self, finalize, *finalize_args, **finalize_kwargs): if self.finalize is not None: raise Exception('ensure() called twice') self.finalize = finalize self.finalize_args = finalize_args self.finalize_kwargs = finalize_kwargs return self def __call__(self): try: return self.fun(*self.args, **self.kwargs) except BaseException as exc: handler = self.find_applicable_handler(exc) if handler is None: raise return handler(exc) finally: if self.finalize is not None: self.finalize() def find_applicable_handler(self, exc): applicable_handlers = ( handler for exception_types, handler in self.exception_types_and_handlers if isinstance(exc, exception_types) ) return next(applicable_handlers, None)



1
投票
StopIteration

并在另一部分捕获它是可以实现的;参见:


from random import randrange list((lambda:(yield from (randrange(0,2) or next(iter(())) for _ in (None,))))())

其中 
next(iter(()))

会引发

StopIteration
,而
yield from
将接住它;上面的表达式根据内部随机值随机返回
[]
[1]
0
将引发异常,而
1
将正常评估)。

您可以阅读更多相关内容

http://baruchel.github.io/python/2018/06/20/python-exceptions-in-lambda/

.


0
投票

toint = lambda x : int(x) strval = ['3', ''] for s in strval: try: print 2 + toint(s) except ValueError: print 2

输出:

5 2

© www.soinside.com 2019 - 2024. All rights reserved.