简体   繁体   中英

Python3: inheriting from list breaks automagically provided __ne__ when __eq__ is defined?

In Python 3, if you provide an __eq__ method, a sensible __ne__ is also typically provided which makes use of your __eq__ . However, I have (in Python 3):

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

And if I do:

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

print (sc != sc2)

I would expect to see:

IN SomeClass EQ
IN SomeOtherClassWhichInheritsFromList EQ
True

But I instead see:

False

Indicating that my __eq__ isn't being called by the default provided __ne__ . If I change SomeOtherClassWhichInheritsFromList to inherit from object instead of list, it works as expected.

Is this because list does not seem to have an __mro__ attribute, and thus all the super() stuff in my __eq__ methods fails to get triggered?

Note: I know I could add my own __ne__ method that calls my __eq__ (which I'll have to do since I do want to inherit from list), but what I'm looking for here is an explanation of why I have to do so.

If you define __eq__ you have to define __ne__ as well, always. From the "Data Model" documentation for Python 3.2: """There are no implied relationships among the comparison operators. The truth of x==y does not imply that x!=y is false. Accordingly, when defining eq (), one should also define ne () so that the operators will behave as expected. """

Python 3 Data Model

What probably happen that you suppose that "In Python 3, if you provide an __eq__ method, a sensible __ne__ is also typically provided which makes use of your __eq__ . " - is that object 's __ne__ method does that. There is no reference to the behavior you state on the Data Model doc - although classes with no explicit superclass (therfore inheriting from object ) behave as you describe.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM