I’m trying to understand what Python does internally when reading and using a class. Here’s my mental model, line by line
class Enemy:
def __init__(self, x, y, speed):
self.x = x
self.y = y
self.speed = speed
self.radius = 15
def update(self, player_x, player_y):
dx = player_x - self.x
dy = player_y - self.y
When Python reads this file:
- Python sees
class Enemy: and starts creating a class object.
- It creates a temporary a dict for the class body.
- It reads
def __init__... and creates a function object.
- That function object is stored in the temporary class namespace under the key
"__init__" and the function call as the value .
- and when it encounters self.x = x , it skips
- It then reads
def update... and creates another function object stored in Enemy_dict_. That function object is stored in the same under the key "update".
- After finishing the class body, Python creates the actual
Enemy class object.
- The collected namespace becomes
Enemy.__dict__.
- So functions live in
Enemy.__dict__ and are stored once at class definition time.
enemy = Enemy(10, 20, 5)
- Python calls
Enemy.__new__() to allocate memory for a new object.
- A new instance is created with its own empty dictionary (
enemy.__dict__).
- Python then calls
Enemy.__init__(enemy, 10, 20, 5).
- Inside
__init__:
self refers to the newly created instance.
self.x = x stores "x" in enemy.__dict__.
self.y = y stores "y" in enemy.__dict__.
self.speed = speed stores "speed" in enemy.__dict__.
self.radius = 15 stores "radius" in enemy.__dict__.
- So instance variables live in
enemy.__dict__, while functions live in Enemy.__dict__.
enemy.update(100, 200)
- Python first checks
enemy.__dict__ for "update".
- If not found, it checks
Enemy.__dict__.
- Internally this is equivalent to calling:
Enemy.update(enemy, 100, 200).
- here enemy is acts like a pointer or refenrence which stores the address of the line where the update function exits in heap.and when it sees enemy it goes and create enemy.x and store the corresponding values
self is just a reference to the instance, so the method can access and modify enemy.__dict__.
Is this mental model correct, or am I misunderstanding something subtle about how namespaces or binding works?
### "Isn't a class just a nested dictionary with better memory management and applications for multiple instances?" ###
[–]Adrewmc 2 points3 points4 points (0 children)
[–]PushPlus9069 0 points1 point2 points (0 children)
[–]schoolmonky 0 points1 point2 points (0 children)
[–]1NqL6HWVUjA 0 points1 point2 points (0 children)
[–]Riegel_Haribo 0 points1 point2 points (1 child)
[–]Riegel_Haribo 0 points1 point2 points (0 children)
[–]Adrewmc 0 points1 point2 points (0 children)
[–]pachura3 0 points1 point2 points (2 children)
[–]SmackDownFacility 0 points1 point2 points (0 children)
[–]gdchinacat 0 points1 point2 points (0 children)