__getattr__ vs __getattribute__ vs __setattr__ 区别
请解释Python中__getattr__、__getattribute__和__setattr__三个魔术方法的区别。它们的调用时机分别是什么?查找优先级如何?在__getattribute__中如何避免无限递归?给出一个实现属性代理或延迟加载的完整示例。
回答
屠龙少年
区别:
| 方法 | 调用时机 | 优先级 |
|---|---|---|
__getattribute__ | 每次访问属性时无条件调用 | 最高,优先于描述符 |
__getattr__ | 当正常属性查找失败(AttributeError)时调用 | 最后兜底 |
__setattr__ | 每次设置属性时调用 | — |
避免无限递归:
def __getattribute__(self, name):
if name == 'secret':
return 'hidden'
return super().__getattribute__(name) # 调用object.__getattribute__
属性代理示例:
class Proxy:
def __init__(self, target):
self._target = target
def __getattr__(self, name):
return getattr(self._target, name)
def __setattr__(self, name, value):
if name.startswith('_'):
super().__setattr__(name, value)
else:
setattr(self._target, name, value)
批量拦截:__setattr__可添加验证逻辑,__getattribute__可实现AOP或权限控制。注意性能开销——每次属性访问都触发调用。