当你只想做一个尝试,只是没有处理异常,你是怎么做到这在Python?
在下面的做的正确方法?
try:
shutil.rmtree(path)
except:
pass
try:
doSomething()
except:
pass
要么
try:
doSomething()
except Exception:
pass
所不同的是,第一个也将赶上KeyboardInterrupt
,SystemExit
之类的东西,这是直接来源于exceptions.BaseException
,不exceptions.Exception
。
详细信息请参见文档:
我需要忽略多个命令错误和fuckit的伎俩
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
简单地提高相关的异常,就像这样:
try:
raise NameError('Joan')
except NameError:
print 'An exception just raised again by Joan!'
raise
就如此容易。 :)
欲了解更多详细信息,请阅读本文档:https://docs.python.org/3.6/tutorial/errors.html
它通常被认为是最佳的做法是只抓到你感兴趣的错误在shutil.rmtree
的情况下,它可能是OSError
:
>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'
如果你想静静地忽略这个错误,你会怎么做:
try:
shutil.rmtree(path)
except OSError:
pass
为什么?假设你(在某种程度上)无意中传递给函数的整数,而不是一个字符串,如:
shutil.rmtree(2)
它会给错误“类型错误:强迫为Unicode:需要字符串或缓冲区,诠释发现” - 你可能不想忽略,这可能是难以调试。
如果你一定要忽略所有的错误,赶上Exception
而不是裸except:
声明。同样,为什么呢?
不指定一个异常捕获每个异常,包括其例如SystemExit
使用sys.exit()
异常:
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
与此相比,以下,其中正确退出:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
如果你想写以往更好运行得代码,该OSError
异常可以代表各种错误,但在上面的例子中,我们只希望忽略Errno 2
,这样我们就可以更加具体:
try:
shutil.rmtree(path)
except OSError, e:
if e.errno == 2:
# suppress "No such file or directory" error
pass
else:
# reraise the exception, as it's an unexpected error
raise
你也可以import errno
和改变if
到if e.errno == errno.ENOENT:
如果你只想做一个尝试捕捉不处理例外,你是怎么做到这一点在Python?
这取决于你的意思是什么“的处理。”
如果你的意思是抓住它没有采取任何行动,您发布的代码将工作。
如果你的意思是你想利用上的异常操作,而不从去向上堆栈停止异常,那么你想是这样的:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
首先,我引用杰克·奥康纳的回答this thread。引用的线程获得封闭,所以我写在这里:
“有一种新的方式来做到这一点在Python 3.4来了:
from contextlib import suppress
with suppress(Exception):
# your code
这里的承诺是增加它:http://hg.python.org/cpython/rev/406b47c64480
而这里的作者,雷蒙德赫廷杰,说起这个和各种其他Python辣味:https://youtu.be/OSGv2VnC0go?t=43m23s
我除了这是Python 2.7等价的:
from contextlib import contextmanager
@contextmanager
def ignored(*exceptions):
try:
yield
except exceptions:
pass
然后你使用它像在Python 3.4:
with ignored(Exception):
# your code
为了完整:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print "division by zero!"
... else:
... print "result is", result
... finally:
... print "executing finally clause"
......从python tutorial。
另外请注意,您可以捕捉这样的例外:
>>> try:
... this_fails()
... except ZeroDivisionError as detail:
... print 'Handling run-time error:', detail
How to properly ignore Exceptions?
有这样做的几种方法。
然而,示例的选择有一个简单的解决方案,它不覆盖的一般情况。
代替
try:
shutil.rmtree(path)
except:
pass
做这个:
shutil.rmtree(path, ignore_errors=True)
这是特定于shutil.rmtree
参数。您可以通过执行以下看到它的帮助下,你会看到它也可以允许在错误的功能良好。
>>> import shutil
>>> help(shutil.rmtree)
由于这仅覆盖了例如狭窄的情况下,我会进一步说明如何处理这一点,如果不存在这些关键字参数。
由于上述仅覆盖例如狭窄的情况下,我会进一步说明如何处理这一点,如果不存在这些关键字参数。
您可以导入suppress
上下文管理器:
from contextlib import suppress
但是,只有抑制最具体的异常:
with suppress(FileNotFoundError):
shutil.rmtree(path)
你会默默地忽略FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
从docs:
与完全抑制异常的任何其他机构,这种情况下管理者应仅用于涵盖与程序的执行被称为是做正确的事默默地继续非常具体的错误。
需要注意的是suppress
和FileNotFoundError
仅可在Python 3。
如果你希望你的代码在Python 2工作为好,请参阅下一节:
当你只想做一个try /只是没有处理异常,你是怎么做到这在Python?
在下面的做的正确方法?
try : shutil.rmtree ( path ) except : pass
对于Python 2代码兼容,pass
是有,这是一个无操作声明的正确方法。但是,当你做裸except:
,这是一样的做except BaseException:
包括GeneratorExit
,KeyboardInterrupt
和SystemExit
,并在一般情况下,你不想要赶上那些东西。
事实上,你应该在命名例外,你可以具体。
下面是Python的(2)exception hierarchy的一部分,你可以看到,如果你捕捉更多的一般例外,你可以隐藏你没有想到的问题:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
... and so on
你可能想在这里赶的OSERROR,也许你不关心的例外是,如果没有目录。
我们可以从errno
库特定的错误,如果我们没有这样的再加注:
import errno
try:
shutil.rmtree(path)
except OSError as error:
if error.errno == errno.ENOENT: # no such file or directory
pass
else: # we had an OSError we didn't expect, so reraise it
raise
注意,裸加薪引发原始异常,这可能是你在这种情况下,想要的东西。写更简洁,因为我们并不真正需要在异常处理代码明确pass
:
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise
如果你只想做一个尝试捕捉不处理例外,你是怎么做到这一点在Python?
这将帮助您打印的例外是什么:(即尽量不捕处理异常和打印除外)。
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
FYI else子句都可以异常之后去,如果在try代码不会导致异常才会运行。
在Python中,我们处理类似其他语言的例外,但不同的是一些语法差异,例如,
try:
#Your code in which exception can occur
except <here we can put in a particular exception name>:
# We can call that exception here also, like ZeroDivisionError()
# now your code
# We can put in a finally block also
finally:
# Your code...