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

如何扩展Python中Generic类的__class_getitem__以支持更多参数?

为Python Generic类扩展__class_getitem__的正确方式

错误原因

当你使用Foo[1, bool]时,Python会把方括号内的所有内容打包成单个元组参数传给__class_getitem__,但你定义的方法要求两个独立参数,因此触发TypeError。

修正方案

让__class_getitem__接收一个元组参数,从中拆分出自定义参数和Generic需要的类型参数,再调用父类的__class_getitem__方法:

from typing import ClassVar, Generic, TypeVar

T = TypeVar("T")

class Foo(Generic[T]):
    cls_attr: ClassVar[int]

    def __class_getitem__(cls, params):
        # 拆分自定义参数与类型参数
        cls_attr, item = params
        cls.cls_attr = cls_attr
        # 调用父类方法处理类型参数
        return super().__class_getitem__(item)

    def __init__(self, arg: T):
        pass

# 测试调用
foo = Foo[1, bool](arg=True)
print(foo.cls_attr)  # 输出: 1
print(type(foo))     # 输出: <class '__main__.Foo[bool]'>

注意事项

  • __class_getitem__的第二个参数默认接收方括号内内容组成的元组,即使只有一个元素也是元组(比如Foo[int]会传入(int,))
  • 直接修改原类的ClassVar属性会影响所有实例和子类。如果需要隔离状态,建议创建动态子类来避免全局污染:
from typing import ClassVar, Generic, TypeVar

T = TypeVar("T")

class Foo(Generic[T]):
    cls_attr: ClassVar[int]

    def __class_getitem__(cls, params):
        cls_attr, item = params
        # 创建动态子类隔离类属性
        class _FooSubclass(cls):
            cls_attr = cls_attr
        # 调用父类方法处理类型参数
        return super(_FooSubclass, _FooSubclass).__class_getitem__(item)

    def __init__(self, arg: T):
        pass

foo1 = Foo[1, bool](arg=True)
foo2 = Foo[2, str](arg="test")
print(foo1.cls_attr)  # 输出: 1
print(foo2.cls_attr)  # 输出: 2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:15:43