Object Instantiation and Class Calls
When you call myobject.method(arg1, arg2), Python automatically converts this into MyClass.method(myobject, arg1, arg2). The object myobject becomes the first argument, which is received as self inside the method. You never explicitly pass self yourself.
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…
What Makes Class Methods Different
Class methods look almost identical to ordinary functions, but they have one critical difference: they require an extra first parameter that you do not provide when calling the method. Python provides this parameter automatically. By convention, this parameter is named self, and it refers to the object instance itself. This is the mechanism that allows a method to access and modify the data belonging to a specific object.
When you call myobject.method(arg1, arg2), Python automatically converts this into MyClass.method(myobject, arg1, arg2). The object myobject becomes the first argument, which is received as self inside the method. You never explicitly pass self yourself.
How Python Binds self During a Method Call
To understand this binding process, let's trace exactly what happens when you call a method. Imagine you have a class called BankAccount and you create an instance called my_account. When you call my_account.withdraw(50), Python performs an invisible transformation: it looks up the withdraw method in the BankAccount class and calls it with my_account as the first argument. Inside the withdraw method, that first argument is received as the self parameter, which now refers to my_account. This is how the method knows which object's data to work with.
Object Instantiation: Creating an Instance
Object instantiation is the process of creating a new instance of a class. You instantiate an object by writing the class name followed by a pair of parentheses. For example, if you have a class called Person, you create an instance by writing my_person = Person(). At this moment, Python creates a new object and that object becomes the value assigned to my_person. The type of my_person is now an instance of the Person class.
Understanding self as an Object Reference
The self parameter is not a special value or a copy of the object. It is a reference to the actual object instance. When a method uses self to access or modify an attribute, it is working directly with that specific object's data. This reference is what allows multiple instances of the same class to maintain separate data. If you create two instances of a class, each one has its own self reference, and each method call operates on the correct instance.
Worked Example: A Simple Bank Account
Creating and Using a Bank Account Object
Define a BankAccount class with a balance attribute and a deposit method. Create two separate account instances, deposit money into each, and trace how self ensures each account maintains its own balance.
- 1Define the class
Create a BankAccount class with an
__init__method that initializes balance to 0. The__init__method is a special method that Python calls automatically when you instantiate the class. It receives self as its first parameter, which refers to the newly created object. - 2Add a deposit method
Define a deposit method that takes self and an amount parameter. Inside the method, use
self.balanceto access and modify that specific object's balance. When you callaccount1.deposit(100), self is bound to account1, soself.balancerefers to account1's balance. - 3Create two instances
Write account1 =
BankAccount()and account2 =BankAccount(). Each call toBankAccount()creates a new object. account1 and account2 are separate objects, each with its own balance attribute initialized to 0. - 4Call methods on each instance
Call
account1.deposit(100)andaccount2.deposit(50). Whenaccount1.deposit(100)executes, Python converts this toBankAccount.deposit(account1, 100), so self is bound to account1. Whenaccount2.deposit(50)executes, self is bound to account2. Each method call modifies the correct object's balance. - 5Verify the results
Print account1.balance and account2.balance. You will see 100 and 50 respectively, confirming that each object maintained its own separate data. The self reference ensured that each method call operated on the correct instance.
account1.balance is 100, account2.balance is 50. Each instance has its own balance because self correctly refers to the specific object on which the method was called.
Comparing Class Methods to Ordinary Functions
| Aspect | Ordinary Function | Class Method |
|---|---|---|
| First parameter | No special first parameter; all parameters are explicitly provided by the caller | Must have a first parameter (by convention named self) that refers to the object instance |
| How parameters are passed | Caller explicitly provides all arguments: function_name(arg1, arg2) | Caller provides only the arguments after self: object.method(arg1, arg2). Python automatically prepends the object as the first argument. |
| Access to data | Cannot access object data unless explicitly passed as an argument | Can access and modify the object's attributes through self without explicit passing |
| Binding | No automatic binding occurs | The object is automatically bound to self when the method is called |
Structural differences between ordinary functions and class methods in parameter handling
Common Mistakes with self and Method Calls
Common mistake Explicitly passing self when calling a method
What it looks likemyobject.method(myobject, arg1, arg2) instead of myobject.method(arg1, arg2)Why it failsPython automatically provides the object as the first argument. If you explicitly pass it, Python will receive two copies of the object: one as self and one as the first regular argument, causing an error about too many arguments.
Do this insteadAlways call methods using the dot notation without explicitly passing the object: myobject.method(arg1, arg2). Python handles the self binding automatically.
Common mistake Forgetting to include self as the first parameter in a method definition
What it looks likedef method(arg1, arg2): instead of def method(self, arg1, arg2):Why it failsWhen Python calls the method, it automatically passes the object as the first argument. If self is not defined as the first parameter, Python will try to assign the object to arg1, leaving arg1 without a value when you call the method with one argument.
Do this insteadAlways include self as the first parameter in every method definition: def method(self, arg1, arg2):
Common mistake Using a different name instead of self
What it looks likedef method(this, arg1): or def method(obj, arg1):Why it failsWhile Python does not technically require the name self (it only cares about position), using a different name violates Python convention and makes your code confusing to other programmers. The first parameter is always the object instance, regardless of its name.
Do this insteadFollow the convention and use self as the name for the first parameter in all methods. This makes your code immediately recognizable to other Python programmers.
Common mistake Assuming self is automatically available without being passed
What it looks likeTrying to use self in a regular function that is not a method
Why it failsself is only automatically provided when a method is called on an object. In a regular function, self is just another variable name with no special meaning. It will not be defined unless you explicitly pass it.
Do this insteadRemember that self is only special inside class methods. Use it only in method definitions, and always as the first parameter.
Why This Mechanism Matters
The automatic binding of self is what makes object-oriented programming possible. Without it, every method would need to receive the object as an explicit argument, and you would need to remember to pass it every time. By automating this binding, Python allows you to write cleaner, more intuitive code. When you read myobject.method(arg1, arg2), it is immediately clear that the method is operating on myobject. The self mechanism is the invisible infrastructure that makes this clarity possible.
Practice: Trace a Method Call
Consider this class definition: class Dog: def __init__(self, name): self.name = name. def bark(self): return self.name + ' says woof!'. Now trace what happens when you execute: my_dog = Dog('Buddy') and then result = my_dog.bark(). For each step, identify: (1) What Python is doing internally, (2) What self refers to at that moment, (3) What value is returned. Write out the transformation that Python performs for the my_dog.bark() call.
Hints
- Remember that
my_dog.bark()is automatically converted by Python intoDog.bark(my_dog). - Inside the bark method, self receives the object that
my_dogrefers to. - When
self.nameis accessed, it looks up the name attribute of that specific object.
Summary
- 1Class methods differ from ordinary functions by requiring a first parameter (conventionally named self) that refers to the object instance. You do not provide this parameter when calling the method; Python provides it automatically.
- 2When you call
myobject.method(arg1, arg2), Python internally converts this toMyClass.method(myobject, arg1, arg2). The object becomes the first argument, which is received as self. - 3Object instantiation creates a new instance of a class by calling the class name with parentheses. Each instance is a separate object with its own data.
- 4self is a reference to the specific object on which the method was called. This allows each instance to maintain its own separate state while using the same method code.
- 5The automatic binding of self is the mechanism that makes object-oriented programming practical. It allows methods to access and modify an object's data without requiring explicit passing of the object as an argument.
At a glance
- Class methods have one critical difference from ordinary functions: they require a first parameter (self) that Python automatically binds to the object instance during method calls.
- When you call
myobject.method(arg1, arg2), Python converts this toMyClass.method(myobject, arg1, arg2), making the object the first argument. - Object instantiation creates a new instance by calling the class name with parentheses, and each instance maintains its own separate data through its own self reference.
- self is not a special keyword but a naming convention; it is simply a reference to the specific object on which the method was called.
- This automatic binding mechanism is what makes object-oriented programming practical and allows clean, intuitive code where methods naturally operate on their objects.