Python NotImplemented常量

时间:2009-06-30 06:52:12

标签: python

通过decimal.py查看,它在许多特殊方法中使用NotImplemented。 e.g。

class A(object):
    def __lt__(self, a):
        return NotImplemented

    def __add__(self, a):
        return NotImplemented

Python docs say

  

NotImplemented

     

“丰富的比较”可以返回的特殊值   特殊方法(__eq__()__lt__(),   和朋友们),以表明   比较没有实现   尊重其他类型。

它没有谈论其他特殊方法,也没有描述行为。

它似乎是一个神奇的物体,如果从其他特殊方法返回引发TypeError,并且在“丰富的比较”中,特殊方法什么都不做。

e.g。

print A() < A()

打印True,但

print A() + 1

引发TypeError,所以我很好奇发生了什么以及NotImplemented的用法/行为是什么。

3 个答案:

答案 0 :(得分:29)

NotImplemented允许您指示两个给定操作数之间的比较尚未实现(而不是指示比较有效,但为两个操作数产生False)。

来自Python Language Reference

  

对于对象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__