You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中重写list等内置类型的__getattr__方法问题

解决Python内置类型无法设置__getattr__的问题

直接给list这类内置类型设置__getattr__会报错,原因是Python的内置类型属于不可修改的类型对象(这里的“不可变”指类型本身的结构不能被修改,和实例的可变性无关),不允许动态添加或修改类级别的魔法方法。

下面提供两种可行的解决方案:

方案1:继承内置类型,实现子类的__getattr__

创建内置类型的子类,在子类中自定义__getattr__方法,这样子类的实例访问不存在的属性时就会触发test():

def test():
    return "触发了test方法!"

class CustomList(list):
    def __getattr__(self, attr_name):
        # 只要访问不存在的属性,就调用test
        return test()

# 使用示例
my_list = CustomList([1, 2, 3])
print(my_list.non_exist_attr)  # 输出:触发了test方法!
print(my_list.append)  # 正常获取内置的append方法

注意:这个方法只对自定义子类的实例生效,原生list实例不受影响。

方案2:用代理类包装原生实例

如果需要让原生的内置类型实例也能触发test(),可以写一个代理类,把原生实例包裹起来,代理类接管属性访问逻辑:

def test():
    return "触发了test方法!"

class ListProxy:
    def __init__(self, original_list):
        self._inner_list = original_list

    def __getattr__(self, attr_name):
        # 先尝试从原生实例获取属性,失败则调用test
        try:
            return getattr(self._inner_list, attr_name)
        except AttributeError:
            return test()

    # 为了让代理类支持list的常规操作,需要实现对应的魔法方法
    def __getitem__(self, index):
        return self._inner_list[index]
    
    def __len__(self):
        return len(self._inner_list)
    
    def __iter__(self):
        return iter(self._inner_list)

# 使用示例
original_list = [1, 2, 3]
proxy_list = ListProxy(original_list)
print(proxy_list.non_exist_attr)  # 输出:触发了test方法!
print(proxy_list.append)  # 正常获取原生append方法
print(proxy_list[0])  # 正常访问索引
print(len(proxy_list))  # 正常获取长度

这种方式需要将原生实例包装成代理对象,但能保留原生实例的所有功能,同时实现自定义的属性访问逻辑。


内容的提问来源于stack exchange,提问作者gutjuri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 22:07:12