CodeWalk

__getattr__ vs __getattribute__ vs __setattr__ 区别

作者:屠龙少年 · 2026-05-30 12:55

请解释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或权限控制。注意性能开销——每次属性访问都触发调用。