2016-02-03 45 views
0

假設我們定義x = C(['0'])其中類C通過Python的運算符重載查詢

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) 

當執行上面的代碼返回「假」定義。 如果我的理解很好,那麼對於12<x,它將是12.__lt__(x),這只不過是type(12).__lt__(12, x)int.__lt__(12, x)。因此,它會嘗試使用標準int類中的__lt__方法。但它應該會拋出錯誤信息,因爲此方法不能理解int與類對象的比較。因此,此異常將在內部進行管理,然後應調用x.__lt__(12)type(x).__lt__(x, 12)。這意味着,最終它應該使用C類

內定義的__lt__方法,但似乎這個類是永遠不會調用,因爲我試圖把一些版畫在這個__lt__C類的方法和print(12<x)總是返回False

請問有人可以詳細解釋一下嗎?

回答

1

你是對的,int.__lt__(12, x)將無法​​正常工作;該方法返回在這種情況下,NotImplemented單:

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

然而,巨蟒然後調用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。你不必自己提出例外。