根据关于习语和反成语的in relation to exceptions的Python文档:“你应该尝试尽可能少地使用你的代码中的除了子句 - 你使用的那些通常会在内部调用成功,或者是主要功能的全能。“分段考虑这句话......
“你应该尝试尽可能少地使用代码中的子句”
像我这样的新手有点困惑,我认为在Python中使用EAFP样式-i.e是一种很好的做法。许多try
和except
语句。或者我错过了这一点?
“你使用的那些通常是在应该总是成功的电话里面”
我不明白这里的意思。
“或主要功能中的全能。”
因此,对于任何抛出异常的代码来说,它只是简单地将它传递给调用堆栈,直到它达到你真正通用的异常处理的最高级别时才是好的风格?
答案 0 :(得分:2)
“你应该尝试尽可能少地使用代码中的子句”
除了例外情况,您的代码很容易丢失:
def solve_linear(mat1, mat2):
det1 = determinant(mat1)
det2 = determinant(mat2)
try:
return det1 / det2
except ZeroDivisionError:
raise NoSolution
在这里,让ZeroDivisionError
传播可能很好。你不需要抓住它。
“你使用的那些通常是在应该总是成功的电话里面”
例如,查看此代码读取文件或返回缓存值。尽管有KeyError
例外,它通常会成功:
def read_file(path):
try:
return cache[path]
except KeyError:
fp = open(path, 'rb')
data = fp.read()
fp.close()
cache[path] = data
return data
“或主要功能中的全能。”
如果您的程序是交互式的,那么您可能希望捕获顶级的几乎所有内容。这是交互式命令行程序的顶部循环:
def main():
while True:
try:
text = raw_input('enter command: ')
cmd = parse_command(text)
except EOFError:
return
except KeyboardInterrupt:
return
except ValueError:
print 'Syntax error'
continue
try:
run_cmd(cmd)
except SystemExit:
raise
except Exception:
traceback.print_exc()
答案 1 :(得分:1)
我认为关键是异常应仅用于“特殊”情况。这就是“在通常会成功的通话中”使用背后的意义。这种情况的一个例子可能是一些计算,在一些非常奇怪的情况下,必须进行除零。然后你可以将它包含在try / except语句中以处理这种可能性。
主要功能中的catch-all适用于同一场景。假设您的计算最终在调用堆栈深处的某处除以零。从这一点开始,你无法继续,因此在失败时正确地使用try / except语句是没有意义的。如果只有一个可以从错误中合理恢复的更高级别更有意义。
他们在文档中给出的示例就是一个例子。当调用'get_status'时,你会希望文件存在。如果没有,那么你有except语句来处理(尽管如上所述,在那种特殊情况下'with'语句要好得多。)
答案 2 :(得分:1)
关于第一点,使用异常的整点是你不必将每一行包装在一起!例如。在C中,错误通常由函数调用的返回值确定。因此,如果要捕获所有错误,则必须在每次调用后检查这些错误。使用Python,您可以将一个(可能很大的)语句块组合在一个try / except块中,并且只处理所有错误一次。
第二点是(如果可能的话)你想要解决接近它们发生点的故障。例如。您正在从网络读取数据并获得零字节。在这种情况下,等待再试一次通常是完全可以的。
最后一点是,有时错误是如此之大以至于无法在低级别处理。例如。如果你试图打开一个不存在的文件,它将失败。并且您的程序无法执行与文件内容有关的任何操作。最好在程序的顶层处理它,并询问用户另一个文件名或退出程序。
答案 3 :(得分:1)
Python哲学通常是“请求宽恕,而不是许可”。但我们的想法是不使用try-except子句来捕获所有可能的错误。理想情况下,每个try-except只会捕获相关的错误。
BAD(未指定特定的例外类型):
a = [1, 2, 3]
i = 3
try:
print a[i]
except:
print "Not found!"
GOOD(仅处理我们期望获得的异常):
a = [1, 2, 3]
i = 3
try:
print a[i]
except IndexError:
print "Not found!"
这一点很重要的原因是我们不会掩盖其他可能的代码错误。如果在此示例中i
为1.8,该怎么办?第一个示例将打印Not Found!
,模糊真实问题,但第二个示例将返回TypeError: list indices must be integers, not float
,让我们知道代码中存在逻辑缺陷。