简体   繁体   中英

How does Python establish equality between objects?

I tracked down an error in my program to a line where I was testing for the existence of an object in a list of objects. The line always returned False, which meant that the object wasn't in the list. In fact, it kept happening, even when I did the following:

class myObject(object):
    __slots__=('mySlot')
    def __init__(self,myArgument):
        self.mySlot=myArgument
print(myObject(0)==myObject(0))        # prints False
a=0
print(myObject(a)==myObject(a))        # prints False
a=myObject(a)
print(a==a)                            # prints True

I've used deepcopy before, but I'm not experienced enough with Python to know when it is and isn't necessary, or mechanically what the difference is. I've also heard of pickling, but never used it. Can someone explain to me what's going on here?

Oh, and another thing. The line

if x in myIterable:

probably tests equality between x and each element in myIterable, right? So if I can change the perceived equality between two objects, I can modify the output of that line? Is there a built-in for that and all of the other inline operators?

  1. It passes the second operand to the __eq__() method of the first.

  2. Incorrect. It passes the first operand to the __contains__() method of the second, or iterates the second performing equality comparisons if no such method exists.

Perhaps you meant to use is , which compares identity instead of equality.

The line myObject(0)==myObject(0) in your code is creating two different instances of a myObject , and since you haven't defined __eq__ they are being compared for identity (ie memory location).

x.__eq__(y) <==> x==y and your line about if x in myIterable: using "comparing equal" for the in keyword is correct unless the iterable defines __contains__ .

print(myObject(0)==myObject(0))        # prints False

#because id(left_hand_side_myObject) != id(right_hand_side_myObject)

a=0
print(myObject(a)==myObject(a))        # prints False

#again because id(left_hand_side_myObject) != id(right_hand_side_myObject)

a=myObject(a)
print(a==a)                            # prints True

#because id(a) == id(a)

myObject(a) == myObject(a) returns false because you are creating two separate instances of myObject (with the same attribute a). So the two objects have the same attributes, but they are different instances of your class, so they are not equal.

If you want to check whether an object is in a list, then yeah,

if x in myIterable

would probably be the easiest way to do that.

If you want to check whether an object has the exact same attributes as another object in a list, maybe try something like this:

x = myObject(a)
for y in myIterable:
    if x.mySlot == y.mySlot:
        print("Exists")
        break

Or, you could use __eq__(self,other) in your class definition to set the conditions for eqality.

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