Python运算符重载查询

时间:2016-02-03 16:36:13

标签: python operator-overloading

假设我们定义了x = C(['0']),其中C类由

定义
class C:
    def __init__(self,los):
        self.los = los

    def __lt__(self,right):
        if type(right) is C:
            return self.los < right.los
        elif type(right) is int:
            return self.los < [d for d in str(right)]
        else:
            raise TypeError('unorderable types: C() < '+type_as_str(right)+'()')

x = C(['0'])
print(12<x)

执行上述代码后,返回&#39; False&#39;。 如果我的理解很好,那么对于12<x,它将是12.__lt__(x),这只不过是type(12).__lt__(12, x)int.__lt__(12, x)。因此,它会尝试在标准__lt__类中使用int方法。但是它应该抛出错误信息,因为这个方法并不理解int与类对象的比较。因此,此异常将在内部进行管理,然后应调用x.__lt__(12)type(x).__lt__(x, 12)。这意味着它最终应该使用C类中定义的__lt__方法。

但似乎从未调用此类,因为我尝试在类__lt__的{​​{1}}方法中放置一些打印件,而C始终返回print(12<x)

有人可以详细解释一下吗?

1 个答案:

答案 0 :(得分:1)

你是对的,int.__lt__(12, x)不起作用;在这种情况下,该方法返回NotImplemented单例:

>>> int.__lt__(12, x)
NotImplemented

然而,Python然后调用type(x).__gt__()而非__lt__作为反向:

>>> class Demo:
...     def __lt__(self, other):
...         print('__lt__ called')
...         return NotImplemented
...     def __gt__(self, other):
...         print('__gt__ called')
...         return NotImplemented
...
>>> 12 < Demo()
__gt__ called
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < Demo()

那是因为你可以通过询问另一个对象12是否大于它来确定12是否小于另一个对象。如果您要求反向(12 > x,那么会调用您的C.__lt__()

>>> 12 > Demo()
__lt__ called
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() > Demo()

请注意, Python 会引发TypeError异常,因为Demo.__gt__()Demo.__lt__()都返回了NotImplemented 。您不必自己提出异常。