Don Draper
Don Draper

Reputation: 541

How does name mangling work when accessing `__attr` inside the class?

I know what data mangling in Python is in general and what its purpose is, but there is one subtle aspect I would like to clarify.

Let's say we have a class:

class P:
    def __init__(self):
        self.x = 10
        self.__y = 20
    
    def get_y(self):
        return self.__y

p = P(); p.__dict__ now has the key _P__y so this is where the data mangling occurred.

My question is, though, how do we access the attribute inside get_y given that there is no __y key in __dict__?

I have a faint guess that there is some magic going on in __getattribute__ and then, after getting AttributeError, in __getattr__.

This confusion makes me think that I don't have a 100% understanding of what __init__ does under the hood.

Upvotes: 2

Views: 520

Answers (1)

chepner
chepner

Reputation: 532218

Name mangling is performed by the compiler, not at runtime. Specifically, in CPython, all the generated byte code assumes that the name of the attribute is _P__y, whenever __y occurs as an attribute in the class statement or a function defined inside the class statement.

>>> import dis
>>> dis.dis(P)
Disassembly of __init__:
  3           0 LOAD_CONST               1 (10)
              2 LOAD_FAST                0 (self)
              4 STORE_ATTR               0 (x)

  4           6 LOAD_CONST               2 (20)
              8 LOAD_FAST                0 (self)
             10 STORE_ATTR               1 (_P__y)
             12 LOAD_CONST               0 (None)
             14 RETURN_VALUE

Disassembly of get_y:
  7           0 LOAD_FAST                0 (self)
              2 LOAD_ATTR                0 (_P__y)
              4 RETURN_VALUE

Upvotes: 2

Related Questions