为什么 NotImplemented 在 Python 3 中是真实的?

Why is NotImplemented truthy in Python 3?

这个问题是由 的答案和讨论引发的。以下片段显示了问题的症结所在:

>>> bool(NotImplemented)
True

我的问题如下:

  1. 为什么决定 NotImplementedbool 值应该是 True?感觉不像蟒蛇。
  2. 有什么我不知道的充分理由吗?文档似乎只是说,"because it is".
  3. 有没有合理使用它的例子?

我认为它不直观的原因(请忽略缺乏最佳实践):

>>> class A:
...     def something(self):
...         return NotImplemented
...
>>> a = A()
>>> a.something()
NotImplemented
>>> if a.something():
...     print("this is unintuitive")
...
this is unintuitive

具有如此负面含义(缺乏实施)的东西会被认为是真实的,这似乎是一种奇怪的行为。

相关文字来自:

NotImplemented

Special value which 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; may be returned by the in-place binary special methods (e.g. __imul__(), __iand__(), etc.) for the same purpose. Its truth value is true.

— From the Python Docs

编辑 1

为了阐明我的立场,我认为 NotImplemented 能够计算为布尔值本身就是一种反模式。我觉得 Exception 更有意义,但普遍的想法是,在评估不同对象之间的比较时,出于性能原因选择常量单例。我想我正在寻找令人信服的理由来说明为什么选择 "the way"。

默认情况下,一个对象被认为是真实的 (bool(obj) == True),除非它的 class 提供了一种覆盖其真实性的方法。在 NotImplemented 的情况下,没有人为 bool(NotImplemented) 到 return False 提供了令人信服的用例,因此 <class 'NotImplementedType'> 从未提供过覆盖.

作为 already explains, all classes in python are considered truthy (bool(obj) returns True) unless they specifically change that via Truth Value Testing. It makes sense in some cases to override that, like an empty list, 0, or False (see a good list ).

然而,NotImplemented 没有令人信服的理由是假的。它是解释器使用的特殊值,只能通过特殊方法返回,不应达到常规 python 代码。

Special value which 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.

Incorrectly returning NotImplemented will result in a misleading error message or the NotImplemented value being returned to Python code.

解释器使用它在方法之间进行选择,或者以其他方式影响行为,就像 bool() 本身的情况一样(它首先检查 __bool__ 然后那么,如果 returns NotImplemented, __len__).

请注意,存在一个 NotImplementedError 异常,大概是因为它实际上是一个操作未实现的错误。在您的具体示例中,class Asomething 可能应该引发此异常。