一、开篇面向对象的“家务活”在 Python 的世界里类就像一个家庭属性就是家里的“物件”。公有public客厅里的电视谁来了都能按开关。保护protected卧室里的衣柜家人可以随便翻外人进来只能看不能摸单下划线_。私有private保险柜里的存折只有主人类内部自己知道密码双下划线__。今天我们就来聊聊如何用 Python 的“门禁系统”把这些物件管得明明白白。二、基础篇三大访问级别演义class Person: def __init__(self, name, age, gender): self.name name # 公有 self.__age age # 私有双下划线 self._gender gender # 保护单下划线 def __str__(self): return f{self.name}, {self.__age}, {self._gender} p Person(张三, 30, 男) print(p.name) # ✅ 正常 print(p._gender) # ⚠️ 可以访问但不建议君子协定 # print(p.__age) # ❌ AttributeError: 找不到三、进阶扩展①撕开“私有”的画皮——Name Mangling名称修饰Python 的私有其实是一层“皇帝的新衣”。它并没有真正锁死数据只是偷偷改了个名字print(dir(p)) # 你会发现一个叫 _Person__age 的东西 print(p._Person__age) # 输出 30 强制访问成功核心结论Python 的私有是“防君子不防小人”。它的目的是防止子类意外重写父类属性而不是为了绝对安全。这也是 Python 社区的名言“We are all consenting adults”我们都是成年人要为自己的行为负责。四、进阶扩展②property的“全家桶”Get/Set/Delete光有私有属性还不够我们得给外部提供优雅的访问通道。使用property装饰器可以让方法像属性一样调用。class Person: def __init__(self, name): self.__name name property def name(self): print(正在读取姓名...) return self.__name name.setter def name(self, value): if 2 len(value) 4: self.__name value else: raise ValueError(名字长度必须在 2~4 之间) name.deleter # 扩展删除器 def name(self): print(f删除姓名 {self.__name} 成功) self.__name None p Person(李四) p.name 王五 # 调用 setter print(p.name) # 调用 getter del p.name # 调用 deleterdeleter 的应用场景当删除属性时需要释放外部资源比如断开数据库连接、清除缓存这时候 deleter 就派上了大用场。五、进阶扩展③保护变量_与子类继承的微妙关系在父类中定义_gender子类可以直接继承并使用它。但是如果子类定义了__age双下划线它会被改写为_SuperPerson__age完全独立于父类的_Person__age。这有效防止了继承链中的命名冲突。六、进阶扩展④性能大杀器__slots__每个 Python 实例默认自带一个__dict__字典用于存储属性。这在大量实例比如游戏中成千上万个敌人时会占用巨量内存。如果你确定类只有固定的几个属性加上__slots__瞬间降低内存占用class Person: __slots__ (__name, __age) # 拒绝动态添加属性 def __init__(self, name, age): self.__name name self.__age age p Person(张三, 30) # p.hobby coding # ❌ AttributeError不允许新增属性面试考点__slots__会牺牲动态赋值的灵活性换取更高的内存访问效率。在大型数据科学或游戏项目中这是必备优化手段。 总结金句封装不是为了“隐藏”而是为了控制。通过property我们让调用者感觉像在操作数据但背后却在执行严谨的逻辑校验。这就是面向对象设计的精髓——接口简单实现复杂。