关于python:异常处理总是很昂贵吗?

Is exception handling always expensive?

我一次又一次地被告知,对于诸如确定类型之类的操作,异常处理是不好的形式,因为异常总是计算上昂贵的。尽管如此,我还是看到了一些帖子(尤其是与Python相关的帖子,比如本文的to-reply),它们建议使用异常处理来达到这个目的。

那么,我想知道是否应该普遍避免抛出和捕获异常,因为它总是计算代价高昂,或者某些语言(如python)是否更好地处理异常,并且允许更自由地使用异常处理。


对于所有编程语言,您不能给出诸如"异常是昂贵的,因此应该避免它们"之类的一般建议。

正如您所怀疑的,在Python中,异常使用得比其他语言(如C++)更为宽松。python强调代码的可读性,而不是原始性能。有一个成语"请求宽恕比请求允许更容易",意思是:比起先检查兼容性,尝试你想要实现的并捕获异常更容易。

宽恕:

1
2
3
4
try:
    do_something_with(dict["key"])
except (KeyError, TypeError):
    # Oh well, there is no"key" in dict, or it has the wrong type

许可:

1
2
3
4
if hasattr(dict,"__getitem__") and"key" in dict:
    do_something_with(dict["key"])
else:
    # Oh well

实际上,在python中,使用for循环的迭代是在hood下实现异常的:iterable在到达末尾时引发StopIteration异常。所以即使你试图避免例外,你也会一直使用它们。


我认为很多都归结于特定的用例。

在您发布的示例中,海报明确地引用了Python的"duck-typing"方面。本质上,您使用生成的异常来确定变量是否具有特定的功能或功能集,而不是手动检查(因为python允许许多动态操作,类可能通过__getattr__访问"split",这使得不可能使用标准if语句检查,因此您尝试使用split如果做不到,我们去计划b)。

另外,在许多Python应用程序中,我们往往不太担心其他应用程序中可能涉及的一些性能细节,因此异常产生的任何开销都是"微不足道的"。


在编写模块TCO时,我遇到了这个问题。在1.0.1alpha版本中,我部署了同一类的三个版本。这个模块是用来计算的,所以我想我可以回答你的问题。

通过将它们嵌入到无异常工作的类中来计算快速操作的速度是两个有异常工作的类的两倍。但是你必须知道,如果你认为在异常之间计算有趣的东西会使差异变得非常微小,那么这样的测试可能毫无意义。没有人会认真关注空循环和空系统之间的时间差,从而引发和捕获异常!

出于这个原因,我决定在发布模块的1.1版本时删除第一个系统。虽然速度有点慢,但我发现依赖异常的系统更加健壮,我将重点放在了它上面。