The Constructor and the self Parameter
The constructor is the __init__ method.
Try it: Classes, Instances and Attributes
How a class creates instances with __init__ and self, why an attribute read checks the instance's __dict__ before the class, why assigning through an instance never changes the class, how a class-level list is shared by every instance, and why obj.method(x) is Class.method(obj, x).
How it works
- Dog(...) makes a new, empty instance and calls Dog.__init__(new_object, ...); self.name = ... stores into that object's __dict__.
- Reading obj.attr looks in obj.__dict__ first, then in the class.
- Assigning obj.attr = value always writes obj.__dict__, so it shadows a class attribute for that one object only.
- Mutating a class-level list (self.tricks.append) changes the one list every instance shares.
- obj.method is found on the class and bound to obj, so obj.method(x) runs Class.method(obj, x).
Default run (30 steps): Ready: class Dog and the statements you picked. Watch where each attribute is found and where each assignment writes. … Finished. Printed: ['sit'] / Wolf / Canis familiaris / Fido is 5.
Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. Object numbers are illustrative, not real id() values.
Loading the simulation…
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.
- 1First call
s =
PartyAnimal('Sally')creates an object and passes the string Sally to the constructor. - 2First initialization
For the object referenced by s, the constructor sets x to 0 and stores Sally in the name attribute.
- 3Second call
j =
PartyAnimal('Jim')creates a completely new object and passes the string Jim to the constructor. - 4Second 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
Common mistake Treating the constructor parameter as the object's attribute
What it looks likeThe constructor receives nam, but the object's stored attribute is name.
Why it failsThe parameter is the incoming value. The assignment
self.name= nam stores that value in the particular object's name attribute.Do this insteadTrace both names separately: nam is the parameter, while self.name is the object's attribute.
Common mistake Forgetting that self identifies the current object
What it looks likeReading self.name = nam as though it selected one permanent object.
Why it failsThe constructor runs for each object being created, and self refers to the object being initialized during that call.
Do this insteadFor each constructor call, ask which object self refers to before tracing the assignment.
Common mistake Assuming objects created from one class share the same attribute values
What it looks likeAssuming that changing Sally's x to 1 also changes Jim's x.
Why it failsEach object maintains its own independent copies of x and name.
Do this insteadTrack 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
0
The two objects contain independent copies of x. Changing Sally's x does not affect Jim's x.
Key Takeaways
- 1The constructor
__init__initializes an object when it is created. - 2Parameters beyond self let each constructor call supply unique initial values.
- 3self identifies the particular object whose attributes are being initialized.
- 4
self.attribute= parameter stores an incoming value in that object's attribute. - 5Objects from the same class maintain independent attribute data, so changing one does not affect another.
At a glance
- 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.