Python"正确方法"中的通用异常处理
时间:2020-03-06 14:40:57 来源:igfitidea点击:
有时我发现自己想执行几个顺序命令,例如:
try: foo(a, b) except Exception, e: baz(e) try: bar(c, d) except Exception, e: baz(e) ...
当仅需要忽略异常时,也会发生相同的模式。
这让人感到多余,语法过多,导致在阅读代码时很难遵循。
在C语言中,我可以使用宏轻松解决这种类型的问题,但是不幸的是,这无法在纯Python中完成。
问题:遇到这种模式时,如何最好地减少代码占用空间并提高代码可读性?
解决方案
如果它们是简单的单行命令,则可以将它们包装在lambda
s中:
for cmd in [ (lambda: foo (a, b)), (lambda: bar (c, d)), ]: try: cmd () except StandardError, e: baz (e)
我们可以将整个内容包装在一个函数中,因此看起来像这样:
ignore_errors (baz, [ (lambda: foo (a, b)), (lambda: bar (c, d)), ])
我发现最好的方法是定义一个像这样的函数:
def handle_exception(function, reaction, *args, **kwargs): try: result = function(*args, **kwargs) except Exception, e: result = reaction(e) return result
但这在实践中感觉并不正确:
handle_exception(foo, baz, a, b) handle_exception(bar, baz, c, d)
在特定情况下,我们可以执行以下操作:
try: foo(a, b) bar(c, d) except Exception, e: baz(e)
或者,我们可以在上面的一个步骤中捕获异常:
try: foo_bar() # This function can throw at several places except Exception, e: baz(e)
如果我们使用的是Python 2.5,则可以使用with
语句
from __future__ import with_statement import contextlib @contextlib.contextmanager def handler(): try: yield except Exception, e: baz(e)
示例现在变为:
with handler(): foo(a, b) with handler(): bar(c, d)
我们可以尝试这样的事情。这模糊地类似于C宏。
class TryOrBaz( object ): def __init__( self, that ): self.that= that def __call__( self, *args ): try: return self.that( *args ) except Exception, e: baz( e ) TryOrBaz( foo )( a, b ) TryOrBaz( bar )( c, d )
如果总是这样,则总是在特定函数引发异常时所需的行为,我们可以使用装饰器:
def handle_exception(handler): def decorate(func): def call_function(*args, **kwargs): try: func(*args, **kwargs) except Exception, e: handler(e) return call_function return decorate def baz(e): print(e) @handle_exception(baz) def foo(a, b): return a + b @handle_exception(baz) def bar(c, d): return c.index(d)
用法:
>>> foo(1, '2') unsupported operand type(s) for +: 'int' and 'str' >>> bar('steve', 'cheese') substring not found