大家好,我是正在实战各种 AI 项目的程序员晚枫。
你有没有见过这样的代码:obj.some_property 看起来像属性访问,但背后其实执行了计算? 或者 obj.load_user 请求一个属性,对象自动帮你从数据库加载?这些都是动态属性和特性的功劳。今天咱们把 __getattr__、__setattr__、__slots__ 这些魔法方法一网打尽。
🎯 getattr 和 __getattribute__:属性访问的拦截器
两者的关键区别
| 方法 | 触发时机 | 使用场景 |
|---|---|---|
__getattr__ | 属性不存在时 | 延迟加载、动态属性 |
__getattribute__ | 每次访问属性时 | 属性访问监控、权限控制 |
__getattr__:延迟加载
1 | class LazyObject: |
__getattribute__:属性访问的全局监控
1 | class MonitoredObject: |
⚠️ 注意:
__getattribute__中必须用super().__getattribute__()访问属性,否则会无限递归!
✏️ setattr 和 __delattr__:属性修改和删除的拦截
__setattr__:控制属性赋值
1 | class ValidatedObject: |
__delattr__:控制属性删除
1 | class ProtectedObject: |
💾 __slots__:内存优化的利器
为什么需要 __slots__?
Python 对象默认用 __dict__ 存储属性,这是一个哈希表,占用大量内存。当你创建百万级实例时,内存浪费非常惊人。__slots__ 用固定数组替代哈希表,大幅节省内存。
基础用法
1 | # 普通类(使用 __dict__) |
批量创建的性能对比
1 | import sys |
slots 的注意事项
1 | class Base: |
🏗️ 实战案例:动态 ORM 模型
1 | class Model: |
🎯 本讲总结
getattr:属性不存在时触发,适合延迟加载和动态属性。缓存后不再触发。
getattribute:每次属性访问都触发,适合全局监控。小心无限递归!
setattr / delattr:拦截属性赋值和删除,适合验证和权限控制。
slots:用固定数组替代 __dict__,百万级实例可节省 40%+ 内存。但牺牲了动态添加属性的灵活性。
实战场景:ORM 模型、延迟加载、属性验证、内存优化。
📚 推荐教材
《Python 编程从入门到实践(第 3 版)》 | 《流畅的 Python(第 2 版)》 | 《CPython 设计与实现》
学习路线: 零基础 → 《从入门到实践》 → 《流畅的 Python》 → 本门课程 → 《CPython 设计与实现》
🎓 加入《流畅的 Python》直播共读营
学到这里,如果你想系统吃透这本书——欢迎加入我的直播共读课。
- 每周直播精讲,逐章拆解核心知识点
- 专属学习群,随时答疑交流
- 试运营特惠:
499 元→ 299 元
👉 【立即报名《流畅的 Python》共读课】:https://mp.weixin.qq.com/s/ivHJwn1nNx5ug4TFrapvGg
🔗 课程导航
💬 联系我
| 平台 | 账号/链接 |
|---|---|
| 微信 | 扫码加好友 |
| B 站 | Python 自动化办公社区 |
主营业务:AI 编程培训、企业内训、技术咨询
🎓 AI 编程实战课程
想系统学习 AI 编程?程序员晚枫的 AI 编程实战课 帮你从零上手!
- 👉 课程报名:点击这里报名,前3讲免费试听
- 👉 免费试看:B站免费试看前3讲,先看看适不适合自己
