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
相关产品推荐
相关产品推荐

