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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 18:42:44