在 class 中访问 `__attr` 时,名称重整如何工作?

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

我知道 Python 中的数据处理一般是什么以及它的目的是什么,但有一个微妙的方面我想澄清一下。

假设我们有一个 class:

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

p = P(); p.__dict__ 现在有密钥 _P__y 所以这是数据重组发生的地方。

我的问题是,如果 __dict__ 中没有 __y 键,我们如何访问 get_y 中的属性?

我有一个微弱的猜测,__getattribute__ 中发生了一些魔法,然后,在得到 AttributeError 之后,在 __getattr__.

这种困惑让我觉得我对 __init__ 的幕后工作没有 100% 的了解。

名称重整由编译器执行,而不是在运行时执行。具体来说,在 CPython 中,只要 __y 作为属性出现在 class 语句中或定义在 class声明。

>>> 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