当前位置: 首页 > 图灵资讯 > 行业资讯> 为什么Python类中的私有属性__name依然可以被外部访问?

为什么Python类中的私有属性__name依然可以被外部访问?

来源:图灵python
时间: 2026-07-30 17:13:03
__name 不是访问控制,而是名称改写:赋值 p.__name = "x" 在不影响原有的情况下创造新的公共属性 _Person__name;p._Person__name 由于更名是单向机械替换,可以直接访问;动态生成 "__name" 不触发改名。

Python 的 __name 不是访问控制机制,而是名称重写(name mangling)规则——它不阻止访问,只改变名称。你可以“访问”,因为解释器根本没有阻止你;你“认为它已经改变了,但没有生效”,因为它创建了一个新的属性,而不是原始的私有变量。

为什么 p.__name = "x" 不影响 get_name() 返回值?

这是最常被误解的一点:这个代码根本没有动类中定义的私有属性,只是给一个例子 p 动态添加了一个名字 __name 公有属性。

  • p.__name = "x" → 新的实例属性 p.__name(类型为公有,与类别定义无关)
  • p._Person__name → 才是 __init__self.__name 实际存储位置
  • get_name() 内部读的是 self._Person__name,自然不受上述行的影响
为什么 p._Person__name 能直接读到值吗?

因为 name mangling 它是单向重命名,而不是加密或权限拦截。解释器只在类定义体中扫描 __xxx 形式名称,并自动替换为 _ClassName__xxx;用这个修饰名访问外面是完全合法的。

  • 所有这种行为 Python 3.x 版本稳定,但属于实现细节,不建议依赖
  • IDE 和静态检查工具(如 mypy)这种写法通常会被警告
  • 如果您在调试过程中临时使用它来检查值,则没有问题;写入业务逻辑相当于主动放弃包装合同
_name__name 根本区别在哪里?

前者是人们看到的协议,后者是解释器的机械更名。它们解决了完全不同的问题。

立即学习“Python免费学习笔记(深入);

Python 3.14.2

Python 3.14.2是Python编程语言于2025年12月5日发布的稳定版本,属于3.14系列的第二次维护更新。该版本包含18个修复项目,重点解决多过程、数据和正则表达模块的回归问题,修复CVE-2025-12084等安全漏洞。这个版本标志着Python发展的一个重要里程碑,即自由线程模式(删除GIL)正式得到官方支持。

下载

  • _name:在运行过程中没有语法或干预,纯粹依靠团队合作和文档约束
  • __name:触发 name mangling,主要目的是避免子类同名属性意外覆盖父类内部字段
  • 例如,子类也被定义 self.__id,它将被改写成 _Child__id,不能和父亲在一起 _Parent__id 冲突
动态生成的 "__name" 字符串不会被接受 mangling

name mangling 只作用于类定义时**字面量出现**的双下划线名。如果在操作过程中拼出,解释器根本不识别。

例如:setattr(self, "__name", "x") 改名不会触发,self.__name 就是真的叫 __name,和 _Person__name 完全无关。

这很容易被忽视——你认为使用双下划线是安全的,所有的保护都绕过了动态设置。