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

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

Python有一个称为的单例NotImplemented

为什么有人想返回NotImplemented而不是提出NotImplementedErrorexceptions?这是否会使查找错误(例如执行无效方法的代码)变得更加困难?

Python has a singleton called NotImplemented.

Why would someone want to ever return NotImplemented instead of raising the NotImplementedError exception? Won’t it just make it harder to find bugs, such as code that executes invalid methods?


回答 0

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

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

总结该链接:

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

It’s because __lt__() and related comparison methods are quite commonly used indirectly in list sorts and such. Sometimes the algorithm will choose to try another way or pick a default winner. Raising an exception would break out of the sort unless caught, whereas NotImplemented doesn’t get raised and can be used in further tests.

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

To summarise that link:

NotImplemented signals to the runtime that it should ask someone else to satisfy the operation. In the expression a == b, if a.__eq__(b) returns NotImplemented, then Python tries b.__eq__(a). If b knows enough to return True or False, then the expression can succeed. If it doesn’t, then the runtime will fall back to the built-in behavior (which is based on identity for == and !=).”


回答 1

因为它们有不同的用例。

引用文档(Python 3.6):

未实现

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

异常NotImplementedError

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

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

Because they have different use cases.

Quoting the docs (Python 3.6):

NotImplemented

should be returned by the binary special methods (e.g. __eq__(), __lt__(), __add__(), __rsub__(), etc.) to indicate that the operation is not implemented with respect to the other type

exception NotImplementedError

[…] In user defined base classes, abstract methods should raise this exception when they require derived classes to override the method, or while the class is being developed to indicate that the real implementation still needs to be added.

See the links for details.


回答 2

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

One reason is performance. In a situation like rich comparisons, where you could be doing lots of operations in a short time, setting up and handling lots of exceptions could take a lot longer than simply returning a NotImplemented value.