如何让类型变量同时用于代码逻辑与类型注解?
解决方案
你遇到的问题核心是Python的类型擦除机制——泛型类型变量T在运行时不会保留具体的类型信息,所以直接在func里用T(42)会报错。不过可以通过自动提取子类的泛型参数来避免重复设置_type属性,具体实现如下:
实现代码
import typing from typing import TypeVar, Generic, get_args T = TypeVar('T') class Base(Generic[T]): _type: typing.Type[T] def __init_subclass__(cls) -> None: # 从子类的原始泛型基类中提取实际类型参数 for base in cls.__orig_bases__: origin = typing.get_origin(base) if origin is Base: cls._type = get_args(base)[0] break else: raise TypeError("子类必须继承带具体类型参数的Base类") def func(self) -> T: return self._type(42) # 子类只需指定泛型参数,无需手动设置_type class A(Base[int]): pass class B(Base[str]): pass # 测试验证 a_instance = A() print(a_instance.func()) # 输出: 42 (类型为int) print(type(a_instance.func())) # 输出: <class 'int'> b_instance = B() print(b_instance.func()) # 输出: "42" (类型为str) print(type(b_instance.func())) # 输出: <class 'str'>
原理说明
__init_subclass__钩子:Python 3.6及以上版本支持这个钩子,当子类继承Base时会自动执行该方法,省去手动初始化的步骤。__orig_bases__属性:这个属性保存了子类继承的原始泛型基类(比如Base[int]),而非Python内部处理后的包装类。get_origin和get_args工具:get_origin用于获取泛型的原始类(比如从Base[int]中拿到Base),get_args则提取出泛型参数(比如从Base[int]中拿到int)。
这样修改后,子类只需要像Base[int]这样指定泛型参数,_type属性会被自动设置,完全避免了重复代码。
内容的提问来源于stack exchange,提问作者eepp
相关产品推荐
相关产品推荐

