5

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

>>> bool(NotImplemented)
True

我的问题如下:

  1. 为什么决定 的boolNotImplemented应该是True?感觉很不合时宜。
  2. 我不知道有什么好的理由吗?文档似乎只是说,“因为它是”。
  3. 有没有以合理的方式使用它的例子?

推理为什么我认为它不直观(请忽略缺乏最佳实践):

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

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

相关文字来自:

未实现

__eq__()二进制特殊方法(例如, __lt__(), __add__(),等)应返回的特殊值,__rsub__()表示该操作未针对其他类型实现;可以由就地二进制特殊方法(例如 , 等)返回__imul__()__iand__()用于相同目的。它的真值是真的。

— 来自Python 文档

编辑 1

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

4

2 回答 2

12

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

于 2019-01-10T18:08:10.880 回答
4

正如公认的答案已经解释的那样,python 中的所有类都被认为是真实的(bool(obj) returns True),除非它们通过真值测试专门改变了这一点。在某些情况下覆盖它是有意义的,例如空列表,0或(请参阅此处False的好列表)。

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

__eq__()二进制特殊方法(例如, __lt__(), __add__(),等)应返回的特殊值,__rsub__()以指示该操作未针对其他类型实现。

错误返回NotImplemented将导致误导性错误消息或NotImplemented返回给 Python 代码的值。

解释器使用它来在方法之间进行选择,或者以其他方式影响行为,就像比较运算符==或其bool()自身的情况一样(它__bool__首先检查,然后,如果它返回NotImplemented, __len__)。

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

于 2019-01-10T21:19:14.947 回答