Python子类关键字参数作用及泛型参数T固定实现问题咨询
问题1解答
- Python 3 支持在类定义的基类列表后传入关键字参数,除了
metaclass这类Python内置保留的特殊参数外,其余自定义关键字参数都会被传递给该类的元类的__new__、__init__方法处理。 - 你看到的
extra=是早年typing模块未稳定阶段的自定义实现参数:当时Generic对应的元类会专门捕获extra参数,将传入的ABC类和当前定义的泛型类做运行时关联,保证isinstance、issubclass检查时,泛型类可以直接复用collections.abc中已有的类型判断逻辑。 - 这类自定义参数没有通用的语法规范,完全由基类对应的元类决定支持哪些参数、实现什么功能,只有使用的基类元类明确支持对应参数时才能传入,否则会直接触发类定义错误。
问题2解答
你当前的写法无法拿到绑定后的int类型,是因为直接把TypeVar赋值给类属性的行为,不会在泛型参数化时自动被替换,T始终是你最开始定义的类型变量占位符。要实现需求可以通过提取参数化基类的类型参数实现,Python 3.9+ 可以直接用特殊类属性__orig_bases__获取参数化的基类信息,示例实现如下:
from typing import TypeVar, Generic, get_args, get_origin T = TypeVar('T') class X(Generic[T]): @classmethod @property def p(cls): # 遍历基类获取参数化的X信息 for base in getattr(cls, '__orig_bases__', []): if get_origin(base) is X: return get_args(base)[0] # 处理直接参数化别名的场景 如Z = X[int] if get_origin(cls) is X: return get_args(cls)[0] raise AttributeError("当前类未绑定泛型参数") class Y(X[int]): pass Z = X[int] print(Y.p) # 输出 <class 'int'> print(Z.p) # 输出 <class 'int'>
如果需要兼容更低版本Python,可以通过自定义元类在类定义阶段就捕获传入的泛型参数,提前赋值给类属性即可。你最初尝试的在基类列表传arg=的思路是可行的,只要给父类实现对应元类,在元类的__init__方法中接收这个参数再绑定到类属性即可,和问题1中extra=参数的实现逻辑完全一致。
内容的提问来源于stack exchange,提问作者Clément Dato
相关产品推荐
相关产品推荐

