python __getattr__ & __setattr__
python中属性查找流程
- 对于my_obj.x表达式,首先检查my_obj实例中有没有名为x的实例属性
- 如果上一步没找到,检查对应的类中有没有名为x的类属性,因为类属性可以作为实例属性的默认值
- 如果上一步没找到,沿着继承树继续查找......
- 如果仍找不到,则会调用__getattr__方法。
__getattr__方法
- __getattr__简单实现
- self._components是实例属性,现在假设其是一个列表 [0, 1, 2, 3]
- 如果我们用my_obj.x来调用,在python属性查找流程中,前三步找不到属性x,那么调用__getattr__方法,根据方法中的逻辑,可以返回列表中的第一个元素 0
- __getattr__方法有两个参数,第一个是self,即实例本身的引用,第二个是属性名的字符串表示形式。
shortcut_names = 'xyzt' def __getattr__(self, name): cls = type(self) # 获取当前类名Vector if len(name) == 1: # 属性名只有一个字符,可能是'xyzt'中的某一个 pos = cls.shortcut_names.find(name) # 查找是否是'xyzt'中的某一个 if 0 <= pos < len(self._components): # 定位位置 return self._components[pos] msg = '{.__name__!r} object has no attribute {!r}' # 失败则抛出属性错误 raise AttributeError(msg.format(cls, name))
__setattr__方法
-
只使用__getattr__会出现问题,如下:
- 通过__getattr__,属性x可以引用到0.0
- 更改v.x的值,此时并没有更改原列表中的值,而是创建了一个新的实例属性x
-
为了在更改__getattr__设置的属性名的时候更改原数据,需要在__setattr__方法里设置具体的行为。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现