Pythonic 异常处理:只捕获特定的 errno
Pythonic exception handling: only catching specific errno
我经常在 python "it is easier to ask for forgiveness then for permission" 中看到它,因此有时认为使用 try except
比 if
更好。
我经常有这样的说法
if (not os.path.isdir(dir)):
os.mkdir(dir).
可能的替代品是
try:
os.mkdir(dir)
except OSError:
pass.
不过,我想说得更具体一些,只忽略 errno.EEXIST
,因为这是预期会发生的唯一错误,我不知道会发生什么。
try:
os.mkdir(dir)
except OSError:
if(OSError.errno != errno.EEXIST):
raise
else:
pass.
似乎可以解决问题。但这真的很笨重,如果我需要大量这些代码块,将会 'pollute' 我的代码并降低可读性。在 Python 2.X 中是否有 pythonic 方法来执行此操作?处理此类案件的标准程序是什么?
编辑:
- 如@Francisco Couzo 所指出的,使用 raise 而不是 raise OSerror
- 我用的是Python2.7
这个例子是例外情况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 更改为您的例外编号。您可以在 this link.
获得更好的解释
如果你用不同的参数多次调用它,把它放在一个函数中:
def catch(d, err):
try:
os.mkdir(d)
except OSError as e:
if e.errno != err:
raise
然后调用传入任意参数的函数:
catch(, "foo", errno.EEXIST)
如果你想要更多,你也可以允许传递多个错误号的选项:
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)
我偶然发现了可能是最优雅的解决方案:创建 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)
这样我就完成了一次创建上下文管理器的丑陋工作,从那时起语法就非常好并且可读了。
我经常在 python "it is easier to ask for forgiveness then for permission" 中看到它,因此有时认为使用 try except
比 if
更好。
我经常有这样的说法
if (not os.path.isdir(dir)):
os.mkdir(dir).
可能的替代品是
try:
os.mkdir(dir)
except OSError:
pass.
不过,我想说得更具体一些,只忽略 errno.EEXIST
,因为这是预期会发生的唯一错误,我不知道会发生什么。
try:
os.mkdir(dir)
except OSError:
if(OSError.errno != errno.EEXIST):
raise
else:
pass.
似乎可以解决问题。但这真的很笨重,如果我需要大量这些代码块,将会 'pollute' 我的代码并降低可读性。在 Python 2.X 中是否有 pythonic 方法来执行此操作?处理此类案件的标准程序是什么?
编辑:
- 如@Francisco Couzo 所指出的,使用 raise 而不是 raise OSerror
- 我用的是Python2.7
这个例子是例外情况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 更改为您的例外编号。您可以在 this link.
获得更好的解释如果你用不同的参数多次调用它,把它放在一个函数中:
def catch(d, err):
try:
os.mkdir(d)
except OSError as e:
if e.errno != err:
raise
然后调用传入任意参数的函数:
catch(, "foo", errno.EEXIST)
如果你想要更多,你也可以允许传递多个错误号的选项:
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)
我偶然发现了可能是最优雅的解决方案:创建 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)
这样我就完成了一次创建上下文管理器的丑陋工作,从那时起语法就非常好并且可读了。