Python中的频繁重复try/except

21 投票
4 回答
6626 浏览
提问于 2025-04-16 23:52

首先,我不太确定我的做法是否正确,所以我欢迎各种建议。

如果在代码中经常重复使用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 块中放入完整的语句,甚至可以放多个语句。

不过要记住,如果你需要反复使用相同的处理方式,这感觉就像是过度处理异常。你确定真的需要这么做吗?

撰写回答