Every Python programmer writes:
obj.method()
But have you ever wondered why Python automatically passes self?
While studying Python internals, I explored how method binding works, how descriptors participate in attribute access, and how Python creates bound method objects behind the scenes.
This article documents that learning journey.
A Simple Example
class Demo:
def hello(self):
print("Hello")
obj = Demo()
obj.hello()
We didn't pass self.
So where did it come from?
Demo.hello(obj)
This produces the same result.
This is the first clue that Python is doing something special behind the scenes.
If obj.hello() and Demo.hello(obj) behave the same way, then Python must somehow be attaching obj automatically when we access the method through an instance.
When Python evaluates:
obj.hello
it does not immediately execute the function.
Instead, Python performs attribute lookup and invokes the descriptor protocol.
The function object is transformed into a bound method object that already contains a reference to obj.
When the method is later called, obj is automatically supplied as the first argument (self).
obj.hello
↓
function.\_\_get\_\_(obj, Demo)
↓
Bound Method Created
↓
self Attached
↓
Method Executes
Complete Notes
This article provides a brief overview.
The complete experiments, explanations, and code examples are available in the GitHub repository:
Top comments (0)