Python中所谓“私有”是通过命名改写实现的约定式保护,即以双下划线开头且不以双下划线结尾的属性名(如__x)在类定义中会被自动重命名为_ClassName__x形式,仅防误用而非强制访问控制。

Python 中没有真正意义上的私有属性,所谓“私有”是通过命名改写(name mangling)机制实现的约定式保护,核心目的是避免子类意外覆盖父类的内部属性。
什么是命名改写(Name Mangling)
当属性名以双下划线 __ 开头(且不以双下划线结尾)时,Python 解释器会自动将其重命名为 _类名__属性名 的形式。这个过程发生在编译阶段,不是运行时动态处理。
- 例如:
self.__value在类Person中会被改写为self._Person__value - 改写只对类定义中直接出现的名称生效,不作用于字符串拼接、
getattr动态访问等场景 - 仅以单下划线开头(如
_value)只是约定“受保护”,不会触发改写
命名改写的触发条件
必须同时满足以下三点才会触发改写:
- 属性名以两个下划线 __ 开头
- 属性名不以两个下划线结尾(即不能是
__init__、__str__这类特殊方法) - 该名称出现在类定义的语句中(比如在
def __init__(self):内写self.__x = 1)
像 obj.__x 这样的外部访问,Python 不会自动改写——它只是找不到这个属性,因为实际存在的是 _ClassName__x。
立即学习“Python免费学习笔记(深入)”;
如何查看和访问改写后的属性
虽然设计初衷是“不让外部直接用”,但 Python 并不阻止你手动访问改写后的名称:
- 可用
dir(obj)查看对象所有属性,找到类似_MyClass__data的名称 - 可直接用
obj._MyClass__data读写(不推荐,破坏封装意图) - 更合理的方式是通过公开方法(getter/setter)或 property 提供可控访问
常见误区与注意事项
命名改写容易被误解为“绝对私有”或“加密”,需注意:
- 它不是访问控制机制,不能防止恶意访问,仅防误用
- 子类若定义同名
__attr,会被改写为不同名称(_Subclass__attr),天然隔离,避免冲突 - 在多重继承中,多个父类的
__x会各自改写,互不影响 - 动态创建属性(如
setattr(obj, '__y', 99))不会触发改写










