2011-08-18 50 views
20

首先,我不确定我的方法是否正确,因此我愿意接受各种建议。经常重复尝试/ Python除外

如果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语句吗?

+0

[Python的?:尝试 - 除了作为一个表达式]的可能重复(http://stackoverflow.com/questions/7088009/python-try-except-as -an-expression) – agf

+0

我和@ kindall昨天刚刚回答了这个问题。 – agf

+0

@agf:这个问题似乎部分相关,谢谢链接。然而,Ned Batchelder的答案似乎有一个好处,就是不需要为需要捕获异常的代码块创建一个函数。 – sutre

回答

24

抽象异常处理是与上下文经理:

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

请记住,您需要反复使用相同的处理方式,感觉很像过度处理异常。你确定你需要这么做吗?

+0

我认为这正是我所期待的,但我可能会过度处理异常。在这些情况下,我只想在文件存在的情况下处理文件。我可以检查它们是否事先存在(os.path.filexists),但从我的理解,它更好地尝试和捕获Python中的异常? – sutre

+0

在这种情况下,捕获* first *异常可能是有意义的,然后跳过关于该文件的所有语句块(如果该文件不存在),但让剩余操作的所有其他异常传播,因为它是不太可能的是,在第一个例外中没有例外,在第二个例外情况下与文件存在相当。 – SingleNegationElimination

+0

@TokenMacGuy:谢谢,这很有道理。我会研究最好的方法是什么。 – sutre

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') 
如果你使用它很多,请使用

1

会是这样的工作:

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