python - 在类内访问 `__attr` 时,名称修改如何工作?

标签 python oop name-mangling

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

假设我们有一个类:

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__ 中发生了一些魔法。

这种困惑让我觉得我并没有 100% 理解 __init__ 的底层功能。

最佳答案

名称修改由编译器执行,而不是在运行时执行。具体来说,在 CPython 中,每当 __y 作为 class 中的属性出现时,所有生成的字节代码都假定属性名称为 _P__y语句或在 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

关于python - 在类内访问 `__attr` 时,名称修改如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65095455/

相关文章:

python - 如何在python中生成文件而不将其保存到磁盘?

c# - 静态不可变默认实例

c++ - GCC C++ 名称修改引用

python - 如何通过Django中的gdata.youtube python库上传youtube视频

python - Tweepy - 排除转推

python - 通过同一垂直线中的圆进行圆识别和画线

windows - 应该使用 "__imp__ApiName@N"还是 "_ApiName@N"?

java - Java 中的动态类加载(枚举)

oop - 何时实现接口(interface)以及何时扩展父类(super class)?

sql - 如何在QDB库中添加用户定义的函数?