TL; DR:当模块没有记录所有错误时要捕获哪些错误?
方案:
我正在尝试使用property lists阅读一系列plistlib
。我无法控制文件。如果无法读取文件,我想跳过它。
我的问题是我应该抓到什么样的错误?
plistlib.readPlist
个文件IOError
和xml.parsers.expat.ExpatError
。
但是我也可以通过错误输入我的输入文件来产生至少IndexError
和AttributeError
。这些未在plistlib
中记录。谁知道其他随机输入文件会产生什么样的附加错误?我不希望我的程序因此而失败。
所以我的问题是。我应该抓到什么?我的理解是,使用通用except
捕获任何错误都不是首选,因为它会掩盖其他错误,例如KeyboardInterrupt
。由于这是一个命令行应用程序,我不想忽略这些事件。
代码:
import plistlib
import sys
def main():
paths = [] # from sys.argv
for path in paths:
try:
plist = plistlib.readPlist(path)
except: # What to catch here?
sys.stderr.write('Couldnt read plist. Ignoring.')
continue
process(plist)
Python 2.7,OS X。
答案 0 :(得分:3)
如果你做得不好,那么except Exception:
就会避免抓住KeyboardInterrupt
或SystemExit
。
然而它会捕获StopIteration
和GeneratorExit
。可能你可以安全地向下移动到捕获StandardError
(不包括那些),因为除了迭代器之外的任何代码通常被认为是错误的让StopIteration
逃脱。但谁知道,也许有一些输入会导致库在耗尽的迭代器上调用next
而不能捕获它。
StandardError
仍会捕获SyntaxError
和TypeError
,这通常是程序员错误的指示,而不是错误的输入。但是没有一个单独的类可以同时捕获LookupError
和MemoryError
(两者都适合捕获)而不是SyntaxError
。所以,如果没有文档或大量测试来确定代码真正抛出的内容,那么就可以了。
请注意,MemoryError
不足以知道错误是暂时的(它可以在另一天或另一台机器上运行)还是永久性的(输入文件太大以至于无法想象的机器能够处理它)。