Pythonic异常处理:只捕获特定的错误

2024-04-30 01:00:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我经常在python中读到“请求原谅比请求许可更容易”,因此有时认为使用try except而不是{}更好。在

我经常有这样的陈述

if (not os.path.isdir(dir)):
    os.mkdir(dir).

可能的替代者是

^{pr2}$

不过,我想更具体地说,只忽略errno.EEXIST,因为这是预期会发生的唯一错误,我不知道会发生什么。在

try:
    os.mkdir(dir)
except OSError:
    if(OSError.errno != errno.EEXIST):
        raise
    else:
        pass.

似乎能搞定。但是如果我需要大量的代码块,这会“污染”我的代码并降低可读性。在Python2.X中有没有一种Python式的方法可以做到这一点?处理此类案件的标准程序是什么?在

编辑:

  • 使用raise代替raise OSerror,正如@Francisco Couzo指出的那样
  • 我使用python2.7

Tags: path代码ifosdirnotraisetry
3条回答

我刚刚偶然发现了一个可能是最优雅的解决方案:创建ignored上下文管理器:

import errno
from contextlib import contextmanager

@contextmanager
def ignorednr(exception, *errornrs):
    try:
        yield
    except exception as e:
        if e.errno not in errornrs:
            raise
        pass


with ignorednr(OSError, errno.EEXIST):
     os.mkdir(dir)

这样一来,我只需要创建一次上下文管理器,从那时起,语法就变得非常好和可读了。在

解决方案取自https://www.youtube.com/watch?v=OSGv2VnC0go。在

此示例用于异常OSError : 17, 'File exists'

     import sys
     try:
         value = os.mkdir("dir")
     except:
         e = sys.exc_info()[:2]
         e = str(e)
         if "17" in e:
             raise OSError #Perform Action
         else:
             pass   

把17号换成你的例外号码。您可以在[linkhttps://docs.python.org/2/library/sys.html#sys.exc_info][1]获得更好的解释

如果使用不同的参数多次调用它,请将其放入函数中:

def catch(d, err):
    try:
        os.mkdir(d)
    except OSError as e:
        if e.errno != err:
            raise

然后调用传递任何参数的函数:

^{pr2}$

如果需要更多,还可以允许传递多个errno的选项:

def catch(d, *errs):
    try:
        os.mkdir(d)
    except OSError as e:
        if e.errno not in errs:
            raise

catch("foo", errno.EEXIST, errno.EPERM)

相关问题 更多 >