Classes and Objects: The Basics
__init__ is a special method that runs automatically when an object is instantiated, marking the beginning of the object's lifecycle.
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…
The First Moment of an Object
When a new object is created from a class, Python automatically calls a special method named __init__. This method marks the beginning of the object's lifecycle and gives you a place to establish the object's initial state.
What do you think happens?
Suppose a class contains an __init__ method and you create a new instance from that class. When does __init__ run?
Reveal answer
Automatically when the new instance is created
__init__ is automatically called whenever a new instance of the class is created. Its job is to initialize the object's attributes to sensible starting values.
From Class to Initialized Instance
A class provides the structure from which objects are created. The important execution path is straightforward: the class is defined, the class is called to create an instance, and the new instance's __init__ method runs automatically. During that call, __init__ assigns the attributes that belong to that particular object.
Writing the Initialization Method
An __init__ method receives self as its first parameter. self refers to the specific object being created. Assigning an attribute through self attaches that attribute to that particular instance. A useful __init__ method initializes every attribute the object will use, so each instance begins in a valid and predictable state.
class Profile:
def __init__(self, name):
self.name = name
self.active = True- 1The class definition introduces Profile as the class from which instances can be created.
- 2The
__init__method is the constructor for the class and is called automatically when a new Profile instance is created. - 3self refers to the specific Profile object currently being initialized.
- 4
self.nameandself.activeare attributes attached to that specific object. - 5Because the assignments occur during
__init__, each created Profile instance receives its own initial set of attributes.
- The class defines the kind of object being created.
__init__runs automatically for each new instance.- self identifies the particular instance being initialized.
- name is an instance attribute whose value comes from the supplied name.
- active is another instance attribute initialized to a starting value.
Seeing the Initial State
Two independent profiles
Use the Profile class to create two objects with different names. Determine what __init__ establishes for each object.
- 1Create the first instance
Calling the class creates one Profile instance. Python automatically runs
__init__for that instance, with self referring to it and name receiving the first name. - 2Initialize its attributes
The method assigns the first object's name attribute and sets its active attribute to True.
- 3Create the second instance
Calling the class again creates another Profile instance. Its own call to
__init__uses a different self, so the second object receives its own attributes. - 4Compare the objects
Both objects have the attributes initialized by
__init__, but each instance has its own separate set of attributes and can have a different name.
Each instance begins with a predictable initial state, and the attributes initialized for one instance are separate from the attributes initialized for the other.
The before-and-after view is about state, not about creating a second class. Before initialization is complete, the object's intended attributes have not yet been established by the method. After __init__ assigns them, the object has the predictable starting state that later code can use.
Class Reuse and Instance Independence
A class can be used to create multiple instances. Those instances come from the same class, but each one has its own separate set of attributes. The class supplies the shared definition of how initialization works; each call that creates an instance gives __init__ a particular self and initializes that instance independently.
| Class | Instance |
|---|---|
| Defines the object structure and initialization behavior | Is one particular object created from the class |
| Provides the __init__ method | Receives its own call to __init__ |
| Can be used to create multiple objects | Has its own separate set of attributes |
The class provides the shared definition; each instance receives an independent initialized state.
Mistakes with __init__
Common mistake Assuming __init__ must be called manually for normal object creation
What it looks likeA learner creates an instance and then tries to call __init__ separately just to initialize it.
Why it fails__init__runs automatically whenever a new instance is created.Do this insteadPlace the object's starting attribute assignments in __init__ and let object creation trigger the method.
Common mistake Treating self as a general-purpose placeholder unrelated to the object
What it looks likeA learner reads self.name without connecting self to the particular instance being constructed.
Why it failsself refers to the specific object being created, so it determines which instance receives the attribute.
Do this insteadRead self.attribute as an attribute attached to the current instance.
Common mistake Expecting two instances to share one independent set of attributes
What it looks likeA learner assumes that initializing one object automatically initializes the other objects created from the same class.
Why it failsEach instance has its own separate set of attributes, initialized by its own call to
__init__.Do this insteadTrace each instance's own __init__ call and its own self reference.
Common mistake Leaving an attribute out of __init__ even though the object will use it
What it looks likeAn object is designed to use a status attribute, but __init__ never gives that attribute a starting value.
Why it failsThe source recommends initializing all attributes an object will use so every instance starts in a valid, predictable state.
Do this insteadInitialize every attribute the object is expected to use inside __init__.
Practice the Execution Trace
Consider a class named Account with an __init__ method that assigns self.owner and self.open. Trace what happens when two Account instances are created with different owner values. Identify when __init__ runs, what self refers to during each call, and why the two instances have separate owner and open attributes.
Hints
- Start with the first class call and identify the instance receiving the first self reference.
- Repeat the trace for the second class call rather than reusing the first instance's self.
- Check that every attribute used by the object receives an initial value in
__init__.
When designing a class, list the attributes an object needs at its initial state, then initialize all of them in __init__. This makes the starting state of every instance valid and predictable and makes the execution trace easier to follow.
Key Takeaways
__init__is the constructor for a Python class and runs automatically when a new instance is created.- The self parameter refers to the specific object being initialized.
- Assignments through self create or initialize attributes for that particular instance.
- Each instance has its own separate set of attributes and its own call to
__init__. - Initialize every attribute an object will use in
__init__so each instance starts in a valid, predictable state.