恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

python类的私有属性和公共属性说明

  • 首页
  • 资讯中心
  • /
  • python类的私有属性和公共属性说明

相关资讯

关于数据规范的教训 2026/10/10 17:56:11
软件评审检查表:从需求到测试的逐项评审实践指南 2026/10/10 17:56:11
翻越围栏检测数据集:VOC与YOLO格式解析及YOLOv8训练实战 2026/10/10 17:51:10

最新资讯

汽车零部件行业MES核心功能与落地实践:从批次追溯到防错管控
基于Python的抖音视频数据分析与可视化系统实战
Python抖音数据分析可视化大屏:从数据清洗到ECharts展示完整实战
3亿token打造AI音乐PV:dshV4.1工作流全拆解
PHP/Laravel如何通过经纬度计算距离获取附近商家
Kettle 5.x ETL实战:从转换到作业,解决数据同步与清洗难题

今日推荐

Codex 总用英文回答?从 AGENTS.md 到 config.toml 的中文输出调优指南
OpenClaw 自定义插件开发完整指南(2026最新版):从 TypeScript 到 npm 发布
基于Spark的电影推荐系统全链路实战:从爬虫到Web展示

本周热门

MR25H40CDF + PIC18F65K40:工业记录仪高可靠存储实战
基于STM32的数控恒压恒流电源设计:从硬件到PID调参全解析
LT9211 MIPI重定时器原理与双路扇出实战指南

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

python类的私有属性和公共属性说明

发布时间:2026/10/10 17:56:11
python类的私有属性和公共属性说明 前言「Python 的私有属性」这个说法本身就不太准确。官方教程里写得很干脆在 Python 中那种「除非在对象内部否则无法访问」的私有实例变量是不存在的。之所以大家还总把它挂在嘴边是因为 Python 提供了两套约定单下划线开头_name表示「这是内部实现细节别依赖」双下划线开头__name则会触发编译器层面的名称改写name mangling把名字变成_类名__name。前者是君子协定后者是防止子类意外撞名的技术手段——两者都不是访问控制。本文只讲可见性约定这一面Python 为什么没有真正的私有、_x/__x/__x__这几类名字各自的含义、名称改写到底改成了什么、以及它在实战中会怎么坑人。代码按 Python 3.8 给出。一、Python 里没有真正的私有在 C / Java 里private是编译器强制执行的从类外部访问会直接编译失败。Python 没有这种机制原因也很直白——属性查找走的是命名空间字典只要你知道名字就能getattr拿到只要你知道实例就能vars(obj)看到它的全部属性。Python 的设计哲学是「我们都是成年人we are all consenting adults here」语言不设路障而是靠命名约定告诉使用者「这块是内部实现」。所以你在实际项目里会看到两种现象并存库作者用_internal命名文档里明说「不要依赖」使用者如果非要访问技术上完全做得到风险自负。理解了这一点后面两节的「约定」与「改写」就不会再被误解成「私有性」。二、单下划线 _x一种约定官方教程一个以单下划线开头的名字如_spam应当被当作非公开 API 的一部分无论它是函数、方法还是数据成员它属于实现细节可能在不通知的情况下改变。约定之外单下划线还有一个真实的、由解释器执行的效果在模块里如果模块没有定义__all__from 模块 import *只会导入不以单下划线开头的名字。也就是说_helper这种名字不会被星号导入带出去。# 适用于 Python 3.8class Cache:def __init__(self):self._store {} # 约定内部存储外部不要直接依赖self.hits 0 # 公开计数def get(self, key):if key in self._store:self.hits 1return self._store.get(key)def put(self, key, value):self._store[key] value注意_store依然可以被c._store或c.__dict__[_store]直接读写。约定保护不了你它只负责让人「一看就懂这是内部的东西」。三、双下划线 __x名称改写以两个或更多下划线开头、且不以两个或更多下划线结尾的标识符只要它出现在类定义内部就会被编译器在生成代码前改写成_类名__标识符。官方规则是类名去掉前导下划线前面再补一个下划线然后拼上标识符本身。举例在名为Wallet的类里self.__balance会被改写成self._Wallet__balance。# 适用于 Python 3.8class Wallet:def __init__(self, balance):self.__balance balance # 编译期改写成 self._Wallet__balancedef deposit(self, amount):if amount 0:raise ValueError(金额必须为正)self.__balance amountdef show(self):return self.__balancew Wallet(100)w.deposit(50)print(w.show()) # 推演输出150print(w.__dict__) # 推演输出{_Wallet__balance: 150}print(w._Wallet__balance) # 推演输出150 —— 用改写后的名字照样能访问最后一行是重点改写不是加密也不是权限控制。资料里说「__x是私有属性」时指的只是「这个属性没有出现在类的公开命名里」而不是「拿不到」。一个vars(w)就把真名暴露了。名称改写真正的用途是避免子类无意覆盖。因为改写的名字里带了类名父类和子类各自的__x会落到不同的名字上# 适用于 Python 3.8class A:def __init__(self):self.__v A # 改写为 _A__vclass B(A):def __init__(self):super().__init__()self.__v B # 改写为 _B__v与 _A__v 互不干扰b B()print(b._A__v, b._B__v) # 推演输出A Bprint(sorted(k for k in b.__dict__ if not k.startswith(__)))# 推演输出[_A__v, _B__v]如果要关注「类名」这一环还得注意一个细节改写的规则是「类名去掉前导下划线、再补一个下划线」。所以Foo、_Foo、__Foo三个类名里出现的__spam都会被改写成_Foo__spam——类名前导下划线的数量不影响结果。若类名全部由下划线组成如_或__则改写是恒等的名字保持原样。四、__x__ 与 x_ 这两类名字名字形式官方性质说明name公开正常 API_name约定非公开单下划线开头实现细节from 模块 import *默认不带它name_约定单下划线结尾用来避开与关键字的冲突如class_、import___name名称改写双下划线开头、不以双下划线结尾改写成_类名__name__name__系统保留双下划线包围属于解释器 / 语言规范官方建议不要自创这种名字要澄清题面里的一个说法单下划线开头又单下划线结尾的名字形如_x_并没有特殊语义它既不会被改写也不属于保留名。真正「保留」的是__x__这一形态——像__init__、__eq__、__slots__都是语言规范占用的名字自己发明一个__my_thing__只会让人误以为它有特殊作用。另外补一句版本背景名称改写是源代码层面的文本变换规则从 Python 2 到 Python 3 没有变化所以在 Python 2 里旧式类和新式类的改写结果是一样的。真正随版本变化的是描述符是否生效——官方文档明确写着旧式类不支持描述符而 Python 2 默认定义的类就是旧式类写成class C(object):才是新式类。Python 2.7 已于2020 年 1 月 1 日停止维护PEP 373现在写类直接class C:即可Python 3 里所有类都是新式类。常见坑点1. 以为__x是真正的私有。❌ 认为定义self.__x之后外部绝对拿不到于是把敏感数据比如密钥放心地放进去。 ✅__x只是被改写成_类名__xvars(obj)或obj._类名__x都能读到要保护数据得靠加密、不落库等真手段。2. 在子类里「覆盖」父类的__x期待多态生效。❌ 父类self.__v、子类也写self.__v指望子类方法能改到父类的那个值。 ✅ 两者被改写成_父类__v和_子类__v是两个独立属性要共享就用单下划线或约定好的公开名字。3. 用getattr(obj, __x)去拿改写过的属性。❌getattr(w, __balance)抛AttributeError以为属性丢了。 ✅ 传改写后的名字getattr(w, _Wallet__balance)或者干脆查vars(w)。4. 把单下划线当成「私有」并依赖它。❌ 在业务代码里直接读写别人库对象的obj._store库一升级就崩。 ✅ 把单下划线理解为「不保证稳定」的实现细节需要长期使用的接口应当由库方提供公开方法。5. 以为下划线开头的名字会被from 模块 import *导出。❌ 定义了_helper()却期望星号导入能带过来。 ✅ 没有__all__时import *只导入非下划线开头的名字确实要导出就在__all__里显式列出。6. 类名前导下划线带来意外撞名。❌ 同时存在Foo与_Foo或__Foo两个类各自都有__spam结果改写名相同、互相干扰。 ✅ 记住Foo、_Foo、__Foo里的__spam都变成_Foo__spam命名时避免这种巧合。7. 以为改名能挡住反射和序列化。❌ 认为__x能躲开vars()、pickle、调试器的眼睛。 ✅ 这些工具看到的都是真实键名如_Wallet__balance改名挡不住任何「有意的」访问。总结需求正确做法是否由解释器强制标记「仅供内部使用」单下划线_name否仅约定import *除外避免子类意外撞名双下划线__name改为_类名__name是编译期改写避开关键字冲突单下划线结尾name_否仅约定使用语言规范接口双下划线包围__name__是语言保留真正保护敏感数据加密 / 不落地 / 服务端校验是靠密码学而非命名一句话收尾Python 的「私有」只有名叫_name的约定和名叫__name的改名没有访问控制把它们当成「提示」而不是「锁」代码设计就不会走偏。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号