Python中“正确”的通用异常处理方法
有时候,我会遇到想要顺序执行几个命令的情况,比如这样:
try:
foo(a, b)
except Exception, e:
baz(e)
try:
bar(c, d)
except Exception, e:
baz(e)
...
这种情况也会出现在需要忽略异常的时候。
这样写感觉有点多余,而且过多的语法让代码看起来很难读懂。
在C语言中,我可以很简单地用宏来解决这个问题,但可惜在纯Python中做不到。
问题是:我该如何减少代码的冗余,提升代码的可读性呢?
6 个回答
4
如果它们只是简单的一行命令,你可以用 lambda
来包裹它们:
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)),
])
16
如果你希望在某个特定的函数出现错误时,总是以这种方式处理,那你可以使用一个装饰器:
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
74
如果你使用的是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)