Python中的频繁重复try/except
首先,我不太确定我的做法是否正确,所以我欢迎各种建议。
如果在代码中经常重复使用try/except语句,有没有好的方法可以缩短它们,或者避免完全写出来呢?
try:
# Do similar thing
os.remove('/my/file')
except OSError, e:
# Same exception handing
pass
try:
# Do similar thing
os.chmod('/other/file', 0700)
except OSError, e:
#Same exception handling
pass
比如,对于一些简单的操作,你可以定义一个异常处理的包装函数,然后传入一个lambda函数:
def may_exist(func):
"Work with file which you are not sure if exists."""
try:
func()
except OSError, e:
# Same exception handling
pass
may_exist(lambda: os.remove('/my/file'))
may_exist(lambda: os.chmod('/other/file', 0700))
这样做的“解决方案”会不会让事情变得不清楚?我是不是应该把所有的try/except语句都写完整呢?
4 个回答
2
我觉得你这个通用的解决方案还不错,不过我不太建议在底部使用那些lambda表达式。我建议你可以像这样传递函数和参数。
def may_exist(func, *args):
"Work with file which you are not sure if exists."""
try:
func(args)
except OSError, e:
# Same exception handling
pass
may_exist(os.remove, '/my/file')
may_exist(os.chmod, '/other/file', '0700')
4
把 may_exist
做成一个装饰器可能会更简洁:
from functools import wraps
def may_exist(func):
@wraps(func):
def wrapper(*args, **kwds):
try:
return func(*args, **kwds)
except OSError:
pass
return wrapper
这样你可以选择:
may_exist(os.remove)('/my/file')
may_exist(os.chmod)('/other/file', 0700)
一次性调用,或者:
remove_if_exists = may_exist(os.remove)
...
remove_if_exists('somefile')
如果你经常使用它。
28
处理异常的最佳方法是使用上下文管理器:
from contextlib import contextmanager
@contextmanager
def common_handling():
try:
yield
finally:
# whatever your common handling is
然后:
with common_handling():
os.remove('/my/file')
with common_handling():
os.chmod('/other/file', 0700)
这样做的好处是,你可以在每个 common_handling 块中放入完整的语句,甚至可以放多个语句。
不过要记住,如果你需要反复使用相同的处理方式,这感觉就像是过度处理异常。你确定真的需要这么做吗?