Defining Equality
Defining Equality#
Recall the Dog
class we wrote in Lesson 13.
class Dog:
def __init__(self, name):
self._name = name
def bark(self):
print(f'{self._name}: Woof!')
d1 = Dog('Chester')
d2 = Dog('Chester')
d3 = d1
print(d1 is d2)
print(d1 is d3)
print(d1 == d2)
With our understanding of is
, the first two examples should hopefully make sense. However, the third example ( d1 == d2
) seems a bit surprising! It seems like these two Dog
s should be considered value equal since they have the exact same state!
Unfortunately, Python does not automatically know how you want to define value-equality between Dog
s. By default, Python will treat ==
on your object to mean the same thing as is
, unless you tell it that value equality should be defined otherwise. In this reading, we will talk about how to tell Python what you want ==
to mean for your object.
To define what ==
should mean, you have to implement a special method called __eq__
. __eq__
will be called whenever you use ==
and its return value ( True
or False
) determines the value of ==
. To be more concrete, x == y
gets translated to x.__eq__(y)
behind the scenes!
So let’s define the __eq__
method so that Dog
s can be compared. Notice we are defining what equality means here for the Dog
class. Let’s define it that two Dog
s are equal if they have the same name (notice we could define it however we want, but with only one field, there aren’t a lot of options).
Note
Even though
_name
is a private field on the
Dog
class, it is okay for one
Dog
to access the private fields of another
Dog
. The rationale here is you are the one that wrote the
Dog
class, so you should know how to use their private fields without causing any errors.
class Dog:
def __init__(self, name):
"""
Creates a new Dog object with the given name
"""
self._name = name
def bark(self):
"""
Prints a message for this dog barking.
"""
# Uses a slightly fancier syntax called string interpolation
# You don't need to be able to write these, but we wanted
# to show off this feature. Everything inside {} gets
# evaluated in Python!
print(f'{self._name}: Woof!')
def __eq__(self, other):
"""
Returns true if other has the same name as this Dog
"""
return self._name == other._name
d1 = Dog('Chester')
d2 = Dog('Chester')
d3 = d1
print(d1 is d2)
print(d1 is d3)
print(d1 == d2)
And now this code block prints what we would expect.