如何使用python lambdas捕获异常

时间:2017-08-21 18:07:18

标签: python exception lambda try-catch

假设Python版本> = 3并调用函数列表。 我想编写一个处理异常的lambda函数。 事实是,它不起作用,当函数抛出异常时,程序返回并且调用堆栈中没有看到executeFunction

怎么做?

def executeFunction(x):
    try:
        x
    except:
        print('Exception caught')


executeFunction(func1())
executeFunction(func2())
executeFunction(func3())
executeFunction(func4())
executeFunction(func5())
executeFunction(func6())

2 个答案:

答案 0 :(得分:7)

如果任何函数调用引发异常,即在仍在评估参数时,将不会调用

def executeFunction(x): try: x() except SomeException: print('Exception caught') executeFunction(func1)

您应该考虑传递 callable ,并在x()子句中调用它:

try/except

lambda引发的任何错误现在都由封闭的from functools import partial def executeFunction(x): try: x() except SomeException: print('Exception caught') executeFunction(partial(func1, arg1, argn)) # executeFunction(lambda: func1(arg1, argn)) 子句处理。

对于带参数的函数,您可以使用dispatcher(或executeFunction)来使用参数推迟调用:

def executeFunction(func):
    def wrapper(*args, **kwargs):
        try:
            func(*args, **kwargs)
        except SomeException:
            print('Exception caught')
    return wrapper

@executeFunction
def func1(arg1, arg2):
    ...
@executeFunction
def func2(arg1):
    ...


func1(arg1, arg2) # -> executeFunction(func1)(arg1, arg2)
func2(arg1)       # -> executeFunction(func2)(arg1)

你也可以利用Python的装饰器语法直接使用对函数本身的调用,而不必直接显式调用{{1}},从调用方那里提供更清晰的代码:

{{1}}

答案 1 :(得分:0)

简短的回答是你无法真正处理表达式中的异常。

更长的答案是:你可以通过使用一些人为的伎俩达到你想要的效果。当然,出于严肃的目的,你不应该这样做,但你在表达式中实际可以做的是:

  • 定义"在飞行中"使用type()setattr()的棘手组合的新表达式,如下所示:

    MyException = (lambda o:
                      setattr(o, '__init__',
                          lambda self: setattr(self,"test", 42))
                   or setattr(o, 'my_funny_method', lambda self:True)
                   or setattr(o, 'my_other_funny_method', lambda self:False)
                   or o)(type("MyException", (BaseException,), {}))
    e = MyException()
    print(type(e), "with attribute test =", e.test)
    print(e.my_funny_method())
    raise e
    
  • 提出任何例外;不仅可以通过执行 ad hoc 操作,还可以根据需要以更一般的方式执行:

    (_ for _ in ()).throw(ZeroDivisionError("Hello World"))
    
  • 通过棘手使用 ad hoc 功能来捕获一些异常,例如迭代器处理StopIteration的方式:

    is_odd = lambda n: ((lambda l:
        (l and l.pop()) or "An exception was caught")
          (list((lambda: (yield from (n if n%2
             else (_ for _ in ()).throw(StopIteration) for _ in (None,))))())))
    print(is_odd(5))
    print(is_odd(8))
    

您可以在http://baruchel.github.io/python/2018/06/20/python-exceptions-in-lambda/了解更多相关信息。