通过decimal.py
查看,它在许多特殊方法中使用NotImplemented
。 e.g。
class A(object):
def __lt__(self, a):
return NotImplemented
def __add__(self, a):
return NotImplemented
NotImplemented
“丰富的比较”可以返回的特殊值 特殊方法(
__eq__()
,__lt__()
, 和朋友们),以表明 比较没有实现 尊重其他类型。
它没有谈论其他特殊方法,也没有描述行为。
它似乎是一个神奇的物体,如果从其他特殊方法返回引发TypeError
,并且在“丰富的比较”中,特殊方法什么都不做。
e.g。
print A() < A()
打印True
,但
print A() + 1
引发TypeError
,所以我很好奇发生了什么以及NotImplemented的用法/行为是什么。
答案 0 :(得分:29)
NotImplemented
允许您指示两个给定操作数之间的比较尚未实现(而不是指示比较有效,但为两个操作数产生False
)。
对于对象x和y,首先
x.__op__(y)
试过了。如果没有实现 或返回NotImplemented, 尝试了y.__rop__(x)
。如果这也是 未实施或退货 NotImplemented,一个TypeError异常 被提出来了。但请参阅以下内容 例外:以前的例外情况 item:如果左操作数是 内置类型的实例或 新式的类和正确的操作数 是一个适当的子类的实例 该类型或类并覆盖 base的
__rop__()
方法,右边 尝试了操作数的__rop__()
方法 在左操作数的__op__()
之前 方法。这样就完成了 子类可以完全覆盖 二元运算符。否则,左边 操作数的__op__()
方法总是如此 接受正确的操作数:当一个 预期给定类的实例, 一个子类的实例 上课总是可以接受的。
答案 1 :(得分:6)
从__add__
返回__lt__
时,它实际上具有相同的含义,不同之处在于Python 2.x正在尝试其他方式在放弃之前比较对象。 Python 3.x确实引发了TypeError。实际上,Python也可以尝试__add__
的其他内容,查看__radd__
和(虽然我对它很模糊)__coerce__
。
# 2.6
>>> class A(object):
... def __lt__(self, other):
... return NotImplemented
>>> A() < A()
True
# 3.1
>>> class A(object):
... def __lt__(self, other):
... return NotImplemented
>>> A() < A()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: A() < A()
有关详细信息,请参阅Ordering Comparisions (3.0 docs)。
答案 2 :(得分:0)
如果您从__add__
返回它,它的行为就像对象没有__add__
方法,并引发TypeError
。
如果从富比较函数返回NotImplemented
,Python的行为就像没有实现的方法一样,也就是说,它会推迟使用__cmp__
。