当你只想做一个try-except而不处理异常时,你在Python中如何做呢?
下面的方法是正确的吗?
try:
shutil.rmtree(path)
except:
pass
当你只想做一个try-except而不处理异常时,你在Python中如何做呢?
下面的方法是正确的吗?
try:
shutil.rmtree(path)
except:
pass
当前回答
我需要忽略多个命令和fuckit的错误
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
其他回答
当你只想做一个try catch而不处理异常时, 用Python怎么做?
这将帮助你打印异常是什么:(即尝试catch而不处理异常并打印异常。)
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
通常认为最佳实践是只捕获您感兴趣的错误。在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: coercing to Unicode: need string or buffer, int found”——你可能不想忽略它,这可能很难调试。
如果你确实想忽略所有错误,捕获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
如何正确地忽略异常?
有几种方法可以做到这点。
然而,例子的选择有一个简单的解决方案,不包括一般情况。
具体到示例:
而不是
try:
shutil.rmtree(path)
except:
pass
这样做:
shutil.rmtree(path, ignore_errors=True)
这是shutil.rmtree特有的参数。您可以通过执行以下操作来查看它的帮助,并且您将看到它还可以允许处理错误的功能。
>>> import shutil
>>> help(shutil.rmtree)
由于这只涵盖了示例的狭窄情况,因此我将进一步演示在这些关键字参数不存在的情况下如何处理它。
一般方法
由于以上内容只涵盖了本例的狭窄情况,因此我将进一步演示在这些关键字参数不存在的情况下如何处理这个问题。
Python 3.4新增功能:
你可以导入抑制上下文管理器:
from contextlib import suppress
但只抑制最具体的例外:
with suppress(FileNotFoundError):
shutil.rmtree(path)
你会默默地忽略FileNotFoundError:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
从文档中可以看出:
与其他完全抑制异常的机制一样, 这个上下文管理器应该只用于覆盖非常特定的错误 静默地继续执行程序是已知的 这是正确的做法。
注意,suppress和FileNotFoundError仅在Python 3中可用。
如果你想让你的代码也能在python2中工作,请参阅下一节:
Python 2和3:
当你只想执行try/except而不处理异常时, 用Python怎么做? 下面的方法是正确的吗? 试一试: shutil。Rmtree(路径) 除了: 通过
对于兼容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
注意,纯raise会引发原始异常,这可能就是您在本例中想要的结果。写得更简洁,因为我们真的不需要在异常处理中显式地传递代码:
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
供您参考,else子句可以放在所有异常之后,只有在try中的代码没有导致异常时才会运行。
首先我引用Jack o'Connor的回答。引用的线程已经关闭,所以我在这里写道:
“在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