The Constructor and the self Parameter
The real power of object-oriented programming is creating multiple instances of a class, each with its own independent data.
One Class, Many Objects
A class becomes especially useful when it creates more than one object. The class provides the shared structure, while each object receives its own data. For example, one PartyAnimal object can begin with the name Sally and another can begin with the name Jim. Both objects come from the same class, but they do not have to contain the same attribute values.
What the Constructor Receives
The constructor is the __init__ method. It has two kinds of parameters. The self parameter refers to the particular object being created. Additional parameters receive values supplied by the caller. Those additional parameters allow each new object to start with customized data.
In this constructor, self identifies the object that is currently being initialized. The parameter nam holds the value passed by the caller. The assignment self.name = nam stores that passed-in value in the name attribute of the particular object identified by self. The assignment self.x = 0 gives that same object its starting x value.
Tracing Two Constructor Calls
Creating Sally and Jim
Trace what happens when two PartyAnimal objects are created with different names.
First call: s = PartyAnimal('Sally') creates an object and passes the string Sally to the constructor.
First initialization: For the object referenced by s, the constructor sets x to 0 and stores Sally in the name attribute.
Second call: j = PartyAnimal('Jim') creates a completely new object and passes the string Jim to the constructor.
Second initialization: For the object referenced by j, the constructor sets x to 0 and stores Jim in the name attribute.
The two objects are both PartyAnimals, but s has name Sally and j has name Jim. Each object has its own x and name attributes.
The separate data is the important point. If Sally's party() method increments her x to 1, Jim's x remains 0. The objects were created from the same class, but each object maintains its own independent copies of its attributes.
The Role of self
self connects the constructor's assignments to one specific object. During the creation of s, self refers to the object referenced by s, so self.name receives Sally and self.x receives 0. During the creation of j, self refers to the new object referenced by j, so that object's name receives Jim and its x receives 0. The same constructor instructions can therefore initialize different objects with different values.
Mistakes with Initialization
Treating the constructor parameter as the object's attribute
The parameter is the incoming value. The assignment self.name = nam stores that value in the particular object's name attribute.
Fix:
Trace both names separately: nam is the parameter, while self.name is the object's attribute.Forgetting that self identifies the current object
The constructor runs for each object being created, and self refers to the object being initialized during that call.
Fix:
For each constructor call, ask which object self refers to before tracing the assignment.Assuming objects created from one class share the same attribute values
Each object maintains its own independent copies of x and name.
Fix:
Track each instance separately. Sally's x can become 1 while Jim's x remains 0.
Practice the Trace
A class uses a constructor with self and nam. You create one object with the name Sally and another with the name Jim. Explain which value is received by nam during each construction, which object self identifies, and what value is stored in each object's name attribute.
Hints
- Separate the two constructor calls.
- For each call, identify the object currently being initialized.
- Follow the assignment self.name = nam.
What do you think happens?
After creating s with Sally and j with Jim, if Sally's party() method increments her x to 1, what is Jim's x?
Reveal answer
Answer: 0
The two objects contain independent copies of x. Changing Sally's x does not affect Jim's x.
Key Takeaways
- The constructor __init__ initializes an object when it is created.
- Parameters beyond self let each constructor call supply unique initial values.
- self identifies the particular object whose attributes are being initialized.
- self.attribute = parameter stores an incoming value in that object's attribute.
- Objects from the same class maintain independent attribute data, so changing one does not affect another.
Key Takeaways
- A single class can serve as a template for creating many distinct objects.
- Constructor parameters provide different initial values for different instances.
- self identifies the object receiving the initialized attributes.
- Each instance keeps its own independent copies of attributes.
- Tracing self.attribute = parameter reveals how constructor data becomes object state.