在Python中经常重复try / except

时间:2011-08-18 13:28:41

标签: python exception

首先,我不确定我的做法是否合适,所以我愿意接受各种建议。

如果在代码中经常重复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 个答案:

答案 0 :(得分:25)

抽象异常处理的最佳方法是使用上下文管理器:

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块中放置完整语句和多个语句。

请记住,您需要一遍又一遍地使用相同的处理感觉很像过度处理异常。你确定你需要这么做吗?

答案 1 :(得分: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')

如果你经常使用它。

答案 2 :(得分:2)

我认为您的通用解决方案没问题,但我不会在底部使用这些lambdas。我建议传递像这样的函数和参数

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')

答案 3 :(得分:1)

这样的事情会起作用吗?

def may_exist(func, *func_args):
    try:
        func(*func_args)
    except OSError as e:
        pass