2012-07-11 42 views
2

在Python 3中,如果您提供__eq__方法,通常還會提供一個合理的__ne__,它使用您的__eq__。不過,我(在Python 3):Python3:當__eq__被定義時,從列表中繼承自動提供__ne__?

class SomeOtherClassWhichInheritsFromList(list): 
    def __init__(self): 
     super().__init__() 
     self.parval = 44 

    def __eq__(self, other): 
     print ("IN SomeOtherClassWhichInheritsFromList EQ") 
     if isinstance(other, SomeOtherClassWhichInheritsFromList): 
      return super().__eq__(other) and self.parval == other.parval 
     return NotImplemented 

class SomeClass(SomeOtherClassWhichInheritsFromList): 
    def __init__(self, val): 
     super().__init__() 
     self.val = val 

    def __eq__(self, other): 
     print ("IN SomeClass EQ") 
     if isinstance(other, SomeClass): 
      return super().__eq__(other) and self.val == other.val 
     return NotImplemented 

如果我做的:

sc = SomeClass(99) 
sc2 = SomeClass(104) 

print (sc != sc2) 

我希望看到:

IN SomeClass EQ 
IN SomeOtherClassWhichInheritsFromList EQ 
True 

但我反而看到:

False 

表明我的__eq__ i不會被默認提供的__ne__所調用。如果我將SomeOtherClassWhichInheritsFromList更改爲從對象而不是列表繼承,它按預期工作。

這是因爲名單似乎並不具有__mro__屬性,從而super()東西都在我__eq__方法不能被觸發?

注意:我知道我可以添加我自己的__ne__方法,該方法調用我的__eq__(我必須這樣做,因爲我確實想從列表繼承),但是我在這裏尋找的是解釋爲什麼我必須這樣做。

回答

4

如果您定義了__eq__,您還必須始終定義__ne__。 從Python 3.2的「數據模型」文檔: 「」「比較運算符之間沒有任何隱含的關係,x == y的真值並不意味着x!= y是false,因此,當定義eq(),我們也應該定義NE(),從而使運營商將像預期的那樣。「」「

Python 3 Data Model

什麼可能發生,你想的是」在Python 3,如果你提供了一個__eq__方法,通常還會提供一個合理的__ne__,它使用您的__eq__。「 - 是object__ne__方法就是這樣做的。沒有提及您在Data Model doc中陳述的行爲 - 儘管沒有顯式超類的類(從object繼承)的行爲與您描述的相同。