Python如何让包含同类对象的列表容器支持直接调用内部对象的同名方法
问题原因
- 你当前重写了
__getattribute__,会拦截所有属性访问,访问属性时直接执行对应方法并返回结果列表,导致返回值是不可调用的列表,触发TypeError - 直接重写
__getattribute__还会覆盖list原生的方法(比如append、pop等),导致容器本身的列表功能失效
解决方案
改用__getattr__实现即可:该魔术方法仅在访问不存在的属性时触发,不会影响列表原生方法。逻辑上先判断属性类型:如果是普通属性直接返回所有实例的属性值列表,如果是方法则返回一个可调用的包装函数,调用时会自动遍历所有实例执行对应方法、透传参数并收集结果。
class foo_list(list): def __init__(self, foo_tuple): super().__init__(foo_tuple) def __getattr__(self, name): # 空列表特殊处理,可按需调整返回逻辑 if not self: return [] # 取第一个实例的对应属性判断类型 attr = getattr(self[0], name) # 可调用对象返回包装函数,透传所有参数 if callable(attr): def wrapper(*args, **kwargs): return [getattr(x, name)(*args, **kwargs) for x in self] return wrapper # 普通属性直接返回所有实例的属性值列表 else: return [getattr(x, name) for x in self]
测试效果
import fe u = fe.foo_list((fe.foo(1,2), fe.foo(3,4))) # 调用方法,和内部实例调用方式完全一致 print(u.multiply()) # 输出:[2, 12] # 访问普通属性 print(u.weight) # 输出:[1, 3] # 列表原生方法不受影响 u.append(fe.foo(5,6)) print(u.multiply()) # 输出:[2, 12, 30]
内容的提问来源于stack exchange,提问作者erg erg
相关产品推荐
相关产品推荐

