异常处理是否总是代价高昂?

4
我一再被告知,对于像确定类型这样的操作,异常处理是不好的形式,因为异常总是计算上昂贵的。然而,我看到了一些帖子(特别是与Python相关的帖子,例如这个的回复),建议使用异常处理来实现这个目的。
那么,是否普遍应该避免抛出和捕获异常,因为它总是计算上昂贵的,还是有些语言,比如Python,更好地处理异常,并且可以更自由地使用异常处理呢?

1
通常在Python中,您在其他领域面临的性能问题比异常的开销更为重要 :) - user3159253
类似问题:http://stackoverflow.com/questions/6092992/why-is-it-easier-to-ask-forgiveness-than-permission-in-python-but-not-in-java - Ferdinand Beyer
3个回答

7

您不能通用地建议所有编程语言都应避免异常,因为在Python中,异常的使用比其他语言(如C ++)更加自由。与原始性能不同,Python强调代码的可读性。有一种说法是“宁愿请求宽恕而不是事先获得许可”,意思是:尝试想要实现的内容并捕获异常要比先检查兼容性容易。

宽恕:

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

权限:

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

实际上,在Python中,使用for循环进行迭代是在幕后使用异常实现的:当到达末尾时,可迭代对象会引发StopIteration异常。因此,即使你试图避免异常,你仍然会一直使用它们。


2
我认为很多情况都与特定的使用场景有关。
在你发布的示例中,发布者明确提到了Python的“鸭子类型”方面。基本上,您使用生成的异常来确定变量是否具有特定的功能或一组功能,而不是手动检查(因为Python允许大量的动态操作,类可能通过__getattr__访问“split”,这使得使用标准if语句进行检查变得不可能,因此您尝试使用分割,如果它不能做到,我们就转到计划B)。
在许多Python应用程序中,我们也倾向于不太担心其他应用程序可能关注的某些性能细节,因此从异常中产生的任何开销都是“微不足道”的。

0
在编写我的模块tco时,我遇到了这个问题。在版本1.0.1alpha中,我实现了三个相同类的版本。该模块旨在进行计算,因此我认为我可以回答你的问题。
通过将快速操作嵌入到工作类中不使用异常来计算,比使用两个带有异常的类计算快两倍。但是您必须知道,如果您认为在异常之间计算有趣的事情会使差异变得非常微小,则这样的测试可能毫无意义。没有人会认真关心空循环和空系统引发和捕获异常之间的时间差异! 出于这个原因,我决定在发布我的模块1.1版本时删除第一个系统。尽管稍慢,但我发现依赖异常的系统更加健壮,因此我专注于它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接