Python中如何动态装饰实例的__getitem__方法?
动态修改单个实例的
__getitem__使[]语法生效 你尝试用MethodType给实例绑定新的__getitem__时遇到两个问题:
a[0]仍返回整数,因为Python的特殊方法(如__getitem__)是从类而非实例中查找的,直接给实例赋值不会被[]语法调用;- 显式调用
a.__getitem__(0)会无限递归,因为新方法内部调用的self.__getitem__已经指向新方法本身。
核心原因
Python处理语法糖(比如[]索引)时,会直接调用type(obj).__getitem__(obj, key),而非实例自身的__getitem__属性。所以要让[]语法生效,必须修改实例所属类的__getitem__方法,但为了不影响其他实例,最佳方式是创建临时子类。
可行解决方案
from types import MethodType class MyClass(): def __init__(self, n : int): self.list_of_items = list(range(n)) def __getitem__(self, idx): return self.list_of_items[idx] def foo(self): return "foo" # 保存原类的__getitem__方法,避免递归 original_getitem = MyClass.__getitem__ def new_getitem(self, idx): # 调用原类的方法,而非实例的方法,防止递归 return str(original_getitem(self, idx)) a = MyClass(10) b = MyClass(10) # 用于验证其他实例不受影响 # 创建临时子类,重写__getitem__ class TempSubclass(MyClass): __getitem__ = new_getitem # 将实例a的类替换为临时子类 a.__class__ = TempSubclass # 测试效果 print(a[0]) # 输出 "0" print(a.__getitem__(0)) # 输出 "0" print(b[0]) # 输出 0,其他实例不受影响
其他说明
如果不需要保留原类的__getitem__逻辑,也可以直接在临时子类中实现全新的逻辑。这种方式的优势是完全隔离了单个实例的修改,不会影响同一类的其他对象。
内容的提问来源于stack exchange,提问作者jeandut
相关产品推荐
相关产品推荐

