为什么返回NotImplemented而不是引发NotImplementedError


Answers:


280

这是因为__lt__()和相关的比较方法非常普遍地间接用于列表排序等。有时,算法会选择其他方法或选择默认的获胜者。除非捕获到异常,否则引发异常将不会发生,但是NotImplemented不会引发异常,可以将其用于进一步的测试中。

http://jcalderone.livejournal.com/32837.html

总结该链接:

NotImplemented信号,运行时,它应该让别人来满足使用,在表达a == b,如果a.__eq__(b)回报率NotImplemented,那么Python尝试b.__eq__(a)。如果b知道的足够多返回TrueFalse,则表达式可以成功。如果没有,那么运行时将退回到内置行为(这是基于身份==!=)“。


5
我会小心使用它,因为此链接在文档末尾指出。
杰森·库恩

16
当Python解释器检查是否a.__eq__(b)返回了NotImplemented时,难道不是就那么容易地捕获NotImplementedError(然后调用b.__eq__(a)或执行其他操作)吗?
Veky

24
@Veky。引发异常可能会有更高的开销。排序操作的任何开销都会被列表的大小放大,因此,即使差异很小,找到更快的实现仍然有意义。您也不想打破循环并重新尝试/捕获实施所需的循环。
SpliFF

3
首先,更快的解决方案是将lt自动合成为反向gt,而不是总是调用会返回NotImplemented的东西-而Python不会这样做。我不认为速度是这里的原因。第二,我不明白你在说什么:回报将需要与加薪一样多的循环。实际上,您可以将return想象为引发一个特殊的Return异常,该异常始终在调用范围内捕获。
Veky

2
>>“由列表的大小放大”至少,除非您对世界应该了解的O(n)排序。
乔纳森·哈特利

106

因为它们有不同的用例。

引用文档(Python 3.6):

未实现

应该由二进制特殊的方法被返回(例如__eq__()__lt__()__add__()__rsub__(),等等),以指示该操作不相对于实施向其他类型

异常NotImplementedError

[...]在用户定义的基类中,当抽象方法要求派生类重写该方法时,或者正在开发该类以指示仍需要添加实际实现时,应引发此异常。

有关详细信息,请参见链接。


13

原因之一是性能。在诸如丰富的比较之类的情况下,您可能会在短时间内进行大量操作,因此设置和处理大量异常可能比直接返回NotImplemented值花费更多的时间。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.