Concepts / Class Definition and Structure

Class Definition and Structure

When the class is instantiated, you provide values for those initialization parameters, not for self; Python supplies self automatically.

  • Programming
Interactive lab

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

  1. Dog(...) makes a new, empty instance and calls Dog.__init__(new_object, ...); self.name = ... stores into that object's __dict__.
  2. Reading obj.attr looks in obj.__dict__ first, then in the class.
  3. Assigning obj.attr = value always writes obj.__dict__, so it shadows a class attribute for that one object only.
  4. Mutating a class-level list (self.tricks.append) changes the one list every instance shares.
  5. 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.

Educational simulation

Loading the simulation…

Objects Before Initialization

Creating an object is more than producing an empty instance. When you create an object from a class, Python automatically runs the class's __init__ method. That method sets up the object's initial state before the object is returned to your code. The result is an object whose required attributes are already available instead of one that needs a series of manual setup steps.

PythonPerson objectnewly created__init__initialization methodyour codereceives objectcreatescalls automaticallysets initial statereturns after initialization
What happens between creating an object and receiving the initialized object in your code?

The Initializer's Role

The __init__ method is a special method that runs automatically when you create an object. Its purpose is to initialize the object's state immediately. You define the setup process once inside the class, and every object created from that class goes through that process automatically.

Definition

__init__ is a special method recognized by Python and called automatically during object creation so that the new object can receive its initial state.

Arguments Become Attributes

The data flow has three stages. First, an argument is supplied when the class is instantiated. Next, Python passes that value into the matching parameter of __init__. Finally, an assignment such as self.name = name binds the parameter's value to an instance attribute. The value then becomes part of that particular object's state.

'Alex'instantiation argumentname__init__ parameterself.nameinstance attributePerson objectname: 'Alex'passed intoused bystores value in
How does a value passed during instantiation move into __init__ and become stored on the object?
Worked example

Tracing Person('Alex')

Determine how the value 'Alex' reaches the resulting Person object's state.

  1. 1
    Instantiation

    The class is instantiated with 'Alex' as its argument.

  2. 2
    Automatic invocation

    Python creates a Person object and immediately calls its __init__ method.

  3. 3
    Parameter binding

    The name parameter inside __init__ receives the value 'Alex'. The self parameter represents the object being initialized.

  4. 4
    Attribute assignment

    The assignment self.name = name stores 'Alex' as the object's name attribute.

  5. 5
    Return to code

    After __init__ finishes, the object is returned to the code that created it, with its name attribute already set.

Result

The resulting Person object has a name attribute containing 'Alex'.

Method Naming and Parameters

The initializer has a distinctive name: two underscores before init and two underscores after it. This naming convention identifies it as a special method with automatic behavior. Like any method, it receives self as its first parameter. After self, you list the parameters needed to initialize the object. When the class is instantiated, you provide values for those initialization parameters, not for self; Python supplies self automatically.

PartRole
__init__The special method name recognized for automatic initialization
selfThe object being initialized
nameAn initialization parameter that receives data supplied during instantiation
self.nameThe instance attribute where the value is stored

Parts of the initializer structure

State Changes During Setup

Before initialization, the newly created Person object exists but has no initialized attributes. During __init__, the supplied name value is assigned through self.name. After the method completes, the same object has a name attribute containing 'Alex'. This is the central state change performed by the initializer.

Person objectno initialized attributesPerson objectinitialized stateAttributesnone initializedname'Alex'contains
How does the Person object's state change when __init__ assigns the name attribute?
In the real world

A class can require several pieces of initialization data. In the source example, instantiating Student with 'Jordan', 12345, and 10 causes __init__ to run with those three arguments. The resulting object has its attributes populated immediately, so no separate attribute-setting steps are needed afterward.

Design Benefits

Best practice

Define the initialization requirements in __init__ rather than relying on later manual assignments. This makes the setup process automatic and consistent for every instance. It also communicates what data an object needs: a declaration such as __init__(self, name, age) tells readers that a Person requires a name and an age.

Common Initialization Mistakes

  • Common mistake

    Writing the initializer without double underscores on both sides of init

    What it looks like
    Using init instead of __init__
    Why it fails

    The distinctive double-underscore name is what identifies this method as the special method Python calls automatically.

    Do this instead

    Use __init__ with two underscores before init and two underscores after it.

  • Common mistake

    Omitting self as the first parameter

    What it looks like

    Defining __init__ with only the initialization data parameter

    Why it fails

    self represents the object being initialized and is required as the first parameter of the method.

    Do this instead

    Place self first, followed by the parameters needed for initialization.

  • Common mistake

    Trying to provide a value for self during instantiation

    What it looks like

    Treating self as one of the values supplied when creating the object

    Why it fails

    Python supplies self automatically when it invokes __init__.

    Do this instead

    Pass values only for the initialization parameters that follow self.

  • Common mistake

    Leaving the parameter as a local setup value instead of binding it to the object

    What it looks like

    Receiving name in __init__ but not assigning it through self.name

    Why it fails

    The value is not made part of the object's instance state unless it is assigned to an instance attribute.

    Do this instead

    Use self to bind the parameter to an instance attribute, as in self.name = name.

  • Common mistake

    Assuming the object is returned before initialization finishes

    What it looks like

    Expecting to receive the object and then have __init__ run later

    Why it fails

    The source describes __init__ as running immediately, before the object is returned to your code.

    Do this instead

    Think of object creation as completing the automatic initialization step before your code receives the object.

Check Your Trace

MEDIUM

Trace the data flow for an object created as Student('Jordan', 12345, 10). Identify the three instantiation arguments, the corresponding __init__ parameters, and the instance attributes that should be populated when initialization finishes.

Hints
  • Python passes the three supplied values into __init__ automatically.
  • self represents the Student object being initialized.
  • Each initialization value becomes part of the object's state when it is bound to an instance attribute.

What do you think happens?

When Person('Alex') finishes, does the resulting object already have its name attribute?

  • Yes, because __init__ has already assigned it

  • No, because __init__ runs after the object is returned

Reveal answer
Answer:

Yes, because __init__ has already assigned it

Python calls __init__ automatically during object creation. The assignment self.name = name stores 'Alex' before the object is returned to your code.

Key Takeaways

  • __init__ is a special method that Python calls automatically when an object is created.
  • The method name uses two underscores before and after init, and self must be its first parameter.
  • Values supplied during instantiation become __init__ parameter values, while self is supplied automatically.
  • Assignments such as self.name = name store initialization data as instance attributes.
  • The object is returned to your code only after __init__ has established its initial state.

Related concepts

More concepts starting with C