We have two different operations occuring here:
- creating two objects;
- comparing them for equality (and printing the result).
If the first case, the relevant operations are:
john = Person('john', 'doe', 25)
jane = Person('jane', 'doe', 25)
The two objects basically follow the same set of events.
- First, the interpreter finds the
Person class, and calls its constructor with three arguments, the strings
'doe', and the integer
- If that succeeds, a new object (an instance of the Person class) is returned, and the interpreter assigns that to the variable named
What do I mean by “constructor”?
The constructor is a special method, or in Python’s case, two methods, which are called to create a new instance of the class. Those two methods are the true constructor, the method called
__new__, and the “initalizer”
__new__ method actually creates the instance in memory; the
__init__ method populates it with whatever data you need.
Don’t worry too much about the difference between them. Almost all classes will only use one or the other, and at this early stage in your journey to learn Python, you only need to care about
So the constructor has created a
Person object, or instance, in memory. Now the
__init__ method is automatically called to populate it with data.
This sets three attributes of the object. (Synonyms for “attribute” may include properties, members, or instance variables. None of those three are quite accurate for Python, so best to stick with attribute.)
self.first_name = first_name
Here, the variable
self represents the current instance being worked on. The part after the dot is the name of the attribute, “first_name”. So we are storing the value of the method parameter “first_name” into the object under the attribute name “first_name”.
And similarly for the other two attributes, “last_name” and “age”.
By the time the
__init__ method runs, the instance has three attributes set, using “john”, “doe” and 25. That instance is then saved in the variable called
Then the interpreter does it all again for the
Now we come to the second operation: comparing the john and jane variables for equality.
First the interpreter locates the objects stored in the variables, which both happen to be
Person objects. That will simplify matters.
The the interpreter will look for the special
__eq__ method, used for implementing equality tests. It fetches that method by looking at the
john variable, so john is “self” and jane is “other”.
(Had you written
jane == john instead, then jane would be “self” and john “other”.)
__eq__ method is executed. It ignores the first_name and last_name attributes, and only cares about the age attribute. If the two instances have the same age, then they are considered to be equal.
Earlier, I said that having both objects be
Person instances makes things simpler. What if they are different?
If the two objects are not from the same class, say you had a Person being compared with a Robot (say), the rules become more complicated. First the interpreter will ask the Person object if it knows how to compare itself to Robots; if it answers “no”, then the interpreter will try again by asking the Robot if it knows how to handle the equality test.
If that also fails, the interpreter will fall back on the ultimate test: it will check to see if the two arguments are the same object in memory, in which case they are equal, otherwise they are considered unequal.