当我调用与 shutil、http 等系统库交互的代码时,我发现自己在处理异常时没有指定异常类型,如果系统处于意外状态(例如文件锁定、网络不可用),所有这些都可能抛出等)
try:
# call something
except:
print("OK, so it went wrong.")
这让我很困扰,因为它还会捕获 SyntaxError 和其他基于程序员错误的异常,而且我看到了避免此类开放式异常处理程序的建议。
是否有一种约定,即所有运行时错误都派生自一些我可以在此处使用的常见异常基类?或者任何不涉及语法错误、模块导入失败等的事情?即使是 KeyError 我也会认为是一个错误,因为如果我不能 100% 确定 key 在那里,我倾向于使用 dict.get()。
我不想列出每一个可能的异常类型,尤其是因为我调用了很多我无法控制的支持代码。
更新:好吧,答案让我意识到我问错了问题——我真正想知道的是是否有 Python 约定或明确建议库编写者使用特定的基它们的异常类,以便将它们与更普通的 SyntaxError 和 friend 分开。
因为如果有图书馆编写者的约定,作为图书馆消费者,我可以对可能抛出的内容做出一般性假设,即使具体情况可能有所不同。不确定这是否更有意义?
再次更新:Sven 的回答最终让我明白,与其放弃并捕获顶层的所有内容,我还可以在较低级别处理和完善异常,因此顶层只需要担心来自下面级别的特定异常类型。
谢谢!
请您参考如下方法:
始终使
tryblock 尽可能小。只捕获您要处理的异常。查看您正在处理的函数的文档。
这可以确保您考虑到可能会发生什么异常,并且考虑到如果发生异常该怎么办。如果发生了您从未想过的事情,您的异常处理代码很可能无论如何都无法正确处理这种情况,因此传播异常会更好。
您说过您“讨厌必须列出每一个可以想到的异常类型”,但通常情况并没有那么糟糕。打开一个文件?捕获 IOError。处理一些库代码?他们通常有自己的异常层次结构和特定的顶级异常——如果您想捕获任何特定于库的异常,只需捕获这个异常。尽可能具体,否则错误迟早会被忽视。
关于 Python 中用户定义异常的约定:它们 usually should be derived from Exception .这也是标准库中大多数用户定义异常的来源,因此您至少应该使用
except Exception:
而不是一个简单的 except 子句,它也捕获 KeyboardInterrupt 和 SystemExit。正如您自己指出的那样,这仍然会捕获很多您不想捕获的异常。
