python中没有真正的私有属性,所谓“私有”是通过命名改写(name mangling)机制实现的约定式保护,核心在于双下划线前缀触发的自动重命名为\_类名\_\_属性名;该机制仅作用于类体中定义的双下划线名称,不阻止访问但避免子类冲突,体现“我们都是有共识的成年人”的设计哲学。

Python中没有真正的私有属性,所谓“私有”是通过命名改写(name mangling)机制实现的约定式保护,核心在于双下划线前缀触发的自动重命名。
什么是命名改写(Name Mangling)
当一个实例属性或方法名以两个下划线开头(如__value),且不以两个下划线结尾时,Python会在编译阶段自动将其重命名为_类名__属性名的形式。这个过程发生在类定义时,与运行时无关。
- 改写只对类内部定义的双下划线名称生效,不作用于动态添加的属性
- 仅限于类体中直接出现的名称,函数内定义的变量不受影响
- 单下划线(如_value)仅为约定,不触发改写,表示“受保护”而非私有
命名改写的实际表现
例如定义class BankAccount:,其中self.__balance = 100,则该属性在实例中真实存储为self._BankAccount__balance:
- 外部直接访问obj.__balance会抛出AttributeError
- 但通过obj._BankAccount__balance仍可读写——说明不是强制访问控制
- 子类中若也定义__balance,会被改写为_Subclass__balance,避免命名冲突
为什么设计成这样?
Python的设计哲学是“我们都是 consenting adults”(我们都是有共识的成年人),不阻止开发者访问,而是通过机制降低意外覆盖和误用概率:
立即学习“Python免费学习笔记(深入)”;
- 防止子类无意中重写父类的“内部”属性
- 避免第三方代码依赖类的内部实现细节
- 保持语言简洁,不引入访问修饰符等语法负担
使用建议与注意事项
合理利用命名改写,但别把它当作安全屏障:
- 内部实现细节优先用单下划线(_helper),更轻量、更常见
- 仅在确实需要避免子类命名冲突时才用双下划线(__init_secret)
- 调试时可用obj.__dict__查看所有属性,包括改写后的名称
- 序列化(如pickle)或反射操作需注意改写名,否则可能出错










