You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python __name__ mangling机制下双下划线属性访问逻辑疑问

Python双前导下划线名称修饰实现逻辑

你观察到的现象本质是Python的双下划线名称修饰是编译期语法转换,而非运行时属性查找逻辑,整个过程和对象本身的属性存储没有关系,具体规则如下:

名称修饰的触发时机与转换规则

  • 当Python编译器处理类定义体的代码时,会自动扫描所有符合规则的标识符:以至少2个前导下划线开头、至多1个尾随下划线结尾(排除前后均为双下划线的魔法方法,比如__init__、__str__这类特殊方法不会被处理)。
  • 对命中规则的标识符,编译器会直接将其重写为_当前类名__原标识符名的格式,再生成对应的字节码。
  • 你代码中__init__方法里的self.__args = a,在编译阶段就已经被替换成了self._A__args = a,所以运行时实际给实例绑定的属性名就是_A__args,这也是dir(self)输出里只有_A__args、没有__args的根本原因——运行时从来就不存在名为__args的实例属性。

类内部访问self.__args正常生效的原因

  • 类定义内部所有对__args的引用,同样会在编译阶段被统一替换为_A__args。你在args属性方法里写的self.__args,实际运行时执行的是self._A__args的属性查找,自然能正常拿到值,和运行时是否存在__args这个属性名没有任何关系。
  • 这种转换是严格限定在类定义体范围的:如果在类外部的代码里写obj.__args,由于这段代码不属于类A的定义体,编译器不会对这里的__args做重写,运行时就会真的去实例上查找__args属性,最终抛出AttributeError。

补充验证

你可以直接在类外部访问修饰后的属性名验证逻辑:

obj = A("check")
print(obj._A__args)  # 直接输出check,和类内部访问self.__args的效果完全一致
# print(obj.__args)  # 取消注释运行会抛出AttributeError: 'A' object has no attribute '__args'

内容的提问来源于stack exchange,提问作者user5319825

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 05:18:20