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

aby*_*byx 251 python exception

Python有一个名为的单例NotImplemented.

为什么有人想要返回NotImplemented而不是提出NotImplementedError异常?难道不会让它更难找到bug,例如执行无效方法的代码吗?

Spl*_*iFF 256

这是因为__lt__()和相关的比较方法在列表排序等中间接使用.有时算法会选择尝试其他方式或选择默认赢家.除非被捕获,否则引发异常将会破坏排序,而NotImplemented不会被提升并可用于进一步的测试.

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

总结一下这个链接:

" NotImplemented向运行时发出信号,告诉其他人应该让其他人满足操作.在表达式中a == b,如果a.__eq__(b)返回NotImplemented,那么Python会尝试b.__eq__(a).如果b知道足够返回True或者False,那么表达式就可以成功.如果没有,那么运行时将会回归到内置行为(基于身份==!=)."

  • @Veky.引发异常可能会产生更高的开销.排序操作中的任何开销都会被列表的大小放大,所以即使差异非常小,找到更快的实现仍然是有意义的.您也不希望突破循环并重新输入try/catch实现所需的循环. (20认同)
  • 当Python解释器检查`a .__ eq __(b)`是否返回NotImplemented时,它不能轻易捕获NotImplementedError(并调用`b .__ eq __(a)`或其他什么)? (16认同)
  • 我会小心使用它,因为这个链接指出文档的末尾. (4认同)
  • 对于第一点,更快的解决方案是自动合成LT作为反向gt,而不是总是调用将返回NotImplemented的东西 - 而Python不会这样做.我不认为速度是这里的原因.而对于第二种情况,我不明白你在说什么:返回将需要尽可能多的突破循环.实际上,您可以将返回视为引发特殊的Return异常,该异常始终在调用范围中捕获. (3认同)
  • >> “按列表大小放大” 至少,除非你有一个世界应该知道的 O(n) 排序。 (2认同)

Pao*_*olo 84

因为他们有不同的用例.

引用文档(Python 3.6):

未实现

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

异常NotImplementedError

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

请参阅链接了解详细信息.

  • 这应该是公认的答案。它甚至比用例更强大,它是意图的指示 - 名称末尾带有 Error 的一个表示发生了错误(因为某些内容未实现),另一个不是错误而是“正确的”行为。我将其比作返回 NaN 或引发 ValueError 之间的区别。 (10认同)

Ric*_*dle 10

一个原因是表现.在丰富的比较情况下,您可以在短时间内进行大量操作,设置和处理大量异常可能比简单地返回NotImplemented值花费更长的时间.


小智 6

NotImplemented函数返回类似于声明该函数无法处理输入,但不是引发异常,而是将控制权转移到另一个称为反射函数的函数,希望反射函数能够处理输入。

首先,与任何函数关联的反射函数是预定义的。其次,当原始函数返回时NotImplemented,解释器运行反射函数,但按输入参数的翻转顺序运行。

你可以在这里找到详细的例子