很抱歉这个长标题,但它似乎对我的问题最具描述性.
基本上,我很难在官方python文档中找到异常信息.例如,在我正在编写的一个程序中,我正在使用shutil libary的move函数:
from shutil import move
move('somefile.txt', '/tmp/somefile.txt')
Run Code Online (Sandbox Code Playgroud)
这工作正常,只要我有/ tmp /的写访问权限,就有足够的磁盘空间,并且满足所有其他要求.
但是,在编写通用代码时,通常很难保证这些因素,因此通常使用异常:
from shutil import move
try:
move('somefile.txt', '/tmp/somefile.txt')
except:
print 'Move failed for some reason.'
Run Code Online (Sandbox Code Playgroud)
我想实际捕获适当的异常抛出而不是只捕获所有内容,但我根本找不到大多数python模块抛出的异常列表.有没有办法让我看看给定函数可以抛出哪些异常,为什么?这样我可以为每个例外做出适当的案例,例如:
from shutil import move
try:
move('somefile.txt', '/tmp/somefile.txt')
except PermissionDenied:
print 'No permission.'
except DestinationDoesNotExist:
print "/tmp/ doesn't exist"
except NoDiskSpace:
print 'No diskspace available.'
Run Code Online (Sandbox Code Playgroud)
答案要点是谁可以将我链接到一些我在官方文档中忽略的相关文档,或者提供一种确定的方法来确定哪些函数抛出了哪些异常,以及为什么.
谢谢!
更新:从给出的答案看来,确实没有100%直接的方法来确定特定功能抛出哪些错误.使用元编程,似乎我可以找出简单的情况并列出一些例外,但这不是一个特别有用或方便的方法.
我想最终会有一些标准来定义每个python函数引发的异常,并且这些信息将包含在官方文档中.在那之前,我想我会允许这些异常通过并为我的用户输出错误,因为这似乎是最理智的事情.
msw*_*msw 12
为了放大Messa,抓住你所期望的失败模式,你知道如何恢复.Ian Bicking写了一篇文章,与Eli Bendersky的笔记一样,解决了一些总体原则.
示例代码的问题在于它不处理错误,只是对它们进行美化并丢弃它们.你的代码并不"知道"如何处理NameError,除了传递它之外没什么应该做的,如果你觉得必须添加细节,请查看Bicking的重新加注.
对于shutil.move但不一定可处理的IOError和OSError是合理的"可预期的" .你的函数的调用者希望它移动一个文件,如果Eli写的那个"契约"被打破了,它本身可能会破坏.
捕捉你可以修复,装饰和重新提升你期望但无法修复的内容,并让调用者处理你没想到的内容,即使"处理"的代码是堆栈中的七个级别main.
与(例如)Java 不同,Python 目前没有声明抛出哪些异常的机制。(在 Java 中,您必须准确定义哪些异常是由什么抛出的,如果您的实用程序方法之一需要抛出另一个异常,那么您需要将其添加到调用它的所有方法中,这很快就会变得无聊!)
因此,如果您想准确地发现 Python 的任何给定位抛出了哪些异常,那么您需要检查文档和源代码。
然而Python有一个非常好的异常层次结构。
如果您研究下面的异常层次结构,您会发现您想要捕获的错误超类称为 StandardError - 这应该捕获正常操作中可能生成的所有错误。将错误转换为字符串将为用户提供关于出了什么问题的合理想法,所以我建议上面的代码应该如下所示
from shutil import move
try:
move('somefile.txt', '/tmp/somefile.txt')
except StandardError, e:
print 'Move failed: %s' % e
Run Code Online (Sandbox Code Playgroud)
异常层次结构
BaseException
|---Exception
|---|---StandardError
|---|---|---ArithmeticError
|---|---|---|---FloatingPointError
|---|---|---|---OverflowError
|---|---|---|---ZeroDivisionError
|---|---|---AssertionError
|---|---|---AttributeError
|---|---|---BufferError
|---|---|---EOFError
|---|---|---EnvironmentError
|---|---|---|---IOError
|---|---|---|---OSError
|---|---|---ImportError
|---|---|---LookupError
|---|---|---|---IndexError
|---|---|---|---KeyError
|---|---|---MemoryError
|---|---|---NameError
|---|---|---|---UnboundLocalError
|---|---|---ReferenceError
|---|---|---RuntimeError
|---|---|---|---NotImplementedError
|---|---|---SyntaxError
|---|---|---|---IndentationError
|---|---|---|---|---TabError
|---|---|---SystemError
|---|---|---TypeError
|---|---|---ValueError
|---|---|---|---UnicodeError
|---|---|---|---|---UnicodeDecodeError
|---|---|---|---|---UnicodeEncodeError
|---|---|---|---|---UnicodeTranslateError
|---|---StopIteration
|---|---Warning
|---|---|---BytesWarning
|---|---|---DeprecationWarning
|---|---|---FutureWarning
|---|---|---ImportWarning
|---|---|---PendingDeprecationWarning
|---|---|---RuntimeWarning
|---|---|---SyntaxWarning
|---|---|---UnicodeWarning
|---|---|---UserWarning
|---GeneratorExit
|---KeyboardInterrupt
|---SystemExit
Run Code Online (Sandbox Code Playgroud)
这也意味着在定义自己的异常时,您应该将它们基于 StandardError 而不是 Exception。
Base class for all standard Python exceptions that do not represent
interpreter exiting.
Run Code Online (Sandbox Code Playgroud)