因为结束生成器不是一个常见的事件(我知道它总是会发生,但它只会发生一次)。抛出异常被认为是昂贵的。如果一个事件将在 99% 的时间内成功并在 1% 的情况下失败,那么使用 try/except 比检查是否可以访问该数据要快得多(请求宽恕比请求许可更容易)。
还有一个偏见,因为这样使用的 try/except 块可能很难理解。流控制可能难以遵循,而 if/else 则更直接。 try/except 意味着您必须跟踪它调用的函数内部的 try 和 语句的流控制(因为它们可能会抛出异常并且它可能会向上传播。if/else 可以仅在评估语句时分支。
有时使用 try/except 是正确的,有时使用 if/else 更有意义。它们中的每一个都存在相关的性能成本。考虑:
a = <some dictionary>
if key in a:
print a[key]
对比
a = <some dictionary>
try:
print a[key]
except KeyError:
pass
如果 key 在 a 中不存在,第一个会更快,如果它存在,只会稍微慢一些(几乎不明显)。如果密钥确实存在,第二个会更快,但如果它不存在,则会慢得多。如果 key 几乎总是存在,则选择第二个。否则,第一个效果更好。
编辑:只需添加一点关于 Python try/except 的内容,这对解决其中一个可读性问题有很大帮助。
考虑从文件中读取。
f = None
try:
f = open(filename, 'r')
... do stuff to the file ...
except (IOError, OSError):
# I can never remember which one of these Python throws...
... handle exception ...
finally:
if f:
f.close()
现在do stuff to the file 中的任何内容都可能引发异常,我们会捕获它。通常,出于这个原因,您尝试在尝试中保留尽可能少的代码。 Python 有一个可选的 else 子句用于 try,只有在 try 运行完成且没有遇到异常时才会运行。
f = None
try:
f = open(filename, 'r')
except (IOError, OSError):
pass
else:
... do stuff to the file ...
finally:
if f:
f.close()
在这种情况下,您不会遇到任何可读性问题,因为 try 中只有一个语句;它是一个 python 标准库函数调用,您只捕获特定的异常。