问题:如何正确忽略异常
当您只想执行try-except但不处理异常时,如何在Python中进行呢?
以下是正确的方法吗?
try:
shutil.rmtree(path)
except:
pass
回答 0
try:
doSomething()
except:
pass
要么
try:
doSomething()
except Exception:
pass
所不同的是,第一个也将赶上KeyboardInterrupt
,SystemExit
和类似的东西,这是直接来源于exceptions.BaseException
,没有exceptions.Exception
。
有关详细信息,请参见文档:
回答 1
通常,仅捕获您感兴趣的错误是最佳实践。在这种情况下,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)
它将给出错误“ TypeError:强制转换为Unicode:需要字符串或缓冲区,找到int” -您可能不想忽略它,这可能很难调试。
如果您确实想忽略所有错误,请抓住Exception
而不是仅仅except:
声明。同样,为什么呢?
不指定异常会捕获所有异常,包括SystemExit
例如sys.exit()
使用的异常:
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
将此与以下内容进行比较,即可正确退出:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
如果您想编写更好的行为代码,则OSError
异常可以表示各种错误,但是在上面的示例中,我们仅想忽略Errno 2
,因此我们可以更加具体:
import errno
try:
shutil.rmtree(path)
except OSError as e:
if e.errno != errno.ENOENT:
# ignore "No such file or directory", but re-raise other errors
raise
回答 2
当您只想尝试捕获而不处理异常时,如何在Python中执行呢?
这取决于您所说的“处理”。
如果您打算不采取任何措施就将其捕获,则发布的代码将起作用。
如果您是想对异常采取措施而又不阻止异常上升,那么您需要这样的东西:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
回答 3
首先,我从这个话题中引述杰克·奥康纳的答案。引用的线程已关闭,所以我在这里写:
“ Python 3.4中引入了一种新的方法:
from contextlib import suppress
with suppress(Exception):
# your code
这是添加了它的提交:http : //hg.python.org/cpython/rev/406b47c64480
这是作者Raymond Hettinger,讨论了这一点以及其他各种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
回答 4
为了完整性:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print("division by zero!")
... else:
... print("result is", result)
... finally:
... print("executing finally clause")
还要注意,您可以像这样捕获异常:
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print("Handling run-time error:", err)
…并重新引发如下异常:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
…来自python教程的示例。
回答 5
如何正确忽略异常?
有几种方法可以做到这一点。
但是,示例的选择具有一个不包含一般情况的简单解决方案。
特定于示例:
代替
try:
shutil.rmtree(path)
except:
pass
做这个:
shutil.rmtree(path, ignore_errors=True)
这是特定于的论点shutil.rmtree
。您可以通过执行以下操作来查看有关此操作的帮助,并且您还将看到它还允许错误处理功能。
>>> import shutil
>>> help(shutil.rmtree)
由于这仅涵盖了示例的狭义情况,因此我将进一步说明如果这些关键字参数不存在,该如何处理。
一般的做法
由于上面仅涵盖了示例的狭义情况,因此我将进一步演示如果这些关键字参数不存在,该如何处理。
Python 3.4的新功能:
您可以导入suppress
上下文管理器:
from contextlib import suppress
但只禁止最具体的exceptions:
with suppress(FileNotFoundError):
shutil.rmtree(path)
您将默默地忽略FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
从文档:
与其他任何完全抑制异常的机制一样,此上下文管理器仅应用于涵盖非常具体的错误,在这些错误中,静默地继续执行程序是正确的做法。
请注意,suppress
并且FileNotFoundError
仅在Python 3中可用。
如果您还希望代码也可以在Python 2中运行,请参阅下一节:
Python 2和3:
当您只想尝试/exceptions而不处理异常时,如何在Python中进行呢?
以下是正确的方法吗?
try : shutil.rmtree ( path ) except : pass
对于与Python 2兼容的代码,这pass
是不执行操作的正确方法。但是,当你做一个光秃秃的except:
,这是一样的做except BaseException:
,其中包括GeneratorExit
,KeyboardInterrupt
,和SystemExit
,一般来说,你不想要赶上那些东西。
实际上,在命名异常时应尽可能具体。
这是Python(2)异常层次结构的一部分,如您所见,如果您捕获了更多常规异常,则可以隐藏您没有想到的问题:
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
回答 6
当您只想尝试捕获而不处理异常时,如何在Python中执行呢?
这将帮助您打印出异常是什么(例如,在不处理异常的情况下尝试捕获并打印异常。)
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
回答 7
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
仅供参考,else子句可以在所有异常之后执行,并且仅在try中的代码不会引起异常的情况下才会运行。
回答 8
我需要忽略多个命令中的错误,fuckit做到了
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
回答 9
在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...
回答 10
我通常只是这样做:
try:
doSomething()
except:
_ = ""