我一直在使用Python编程,遇到了一个可能很普遍的问题。我有五个语句都会出现抛出FooException和BarException的情况。我想要运行每个语句,防止这些异常的发生,但即使在处理后抛出异常,也要继续处理。现在,我可以像这样实现:
try:
foo()
except (FooException, BarException):
pass
try:
bar()
except (FooException, BarException):
pass
try:
baz()
except (FooException, BarException):
pass
try:
spam()
except (FooException, BarException):
pass
try:
eggs()
except (FooException, BarException):
pass
但那真的太冗长了,且严重违反DRY原则。一种相当暴力和显然的解决方案是这样的:
def wish_i_had_macros_for_this(statements, exceptions, gd, ld):
""" execute statements inside try/except handling exceptions with gd and ld
as global dictionary and local dictionary
statements is a list of strings to be executed as statements
exceptions is a list of strings that resolve to Exceptions
gd is a globals() context dictionary
ld is a locals() context dictionary
a list containing None or an Exception if an exception that wasn't
guarded against was raised during execution of the statement for each
statement is returned
"""
s = """
try:
$STATEMENT
except (%s):
pass
""" % ','.join(exceptions)
t = string.Template(s)
code = [t.substitute({'STATEMENT': s}) for s in statements]
elist = list()
for c in code:
try:
exec c in gd, ld
elist.append(None)
except Exception, e:
elist.append(e)
return elist
使用方式如下:
>>> results = wish_i_had_macros_for_this(
['foo()','bar()','baz','spam()','eggs()'],
['FooException','BarException'],
globals(),
locals())
[None,None,None,SpamException,None]
有更好的方法吗?
for fn in (foo, bar, ...)
),并使用问题中的代码。但这个execute_silently
函数非常整洁。 - Jean-Francois T.