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

如何在Python中实例化类型提示指定的泛型类?

在Python泛型中实例化类型参数R(类似C#的new()约束)

Python的TypeVar仅作为静态类型提示存在,运行时不会保留泛型参数的实际类型,所以直接写R()会报错——此时R只是一个TypeVar对象,并非实际的类。以下是两种可行的实现方式:

方案一:显式传入目标类型(推荐,兼容性好)

在初始化泛型类时,直接传入要实例化的类型并保存,后续方法中使用保存的类型构造实例,符合Python"显式优于隐式"的设计原则。

from typing import TypeVar, Generic, Type

class BaseParams(object):
     def __init__(self) -> None:
          self.name = 'set-in-base-class'

class ChildParams(BaseParams):
     def __init__(self) -> None:
          super().__init__()
          self.name = 'set-in-child-class'

R = TypeVar('R', bound=BaseParams)

class MyGeneric(Generic[R]):
     def __init__(self, r_type: Type[R]) -> None:
          self.r_type = r_type
     def test(self):
          r = self.r_type()
          print(r.name)

# 使用示例
c = MyGeneric[ChildParams](ChildParams)
c.test()  # 输出: set-in-child-class

方案二:利用运行时类型信息(Python 3.8+)

通过PEP 560引入的__orig_class__属性,结合typing.get_args提取泛型参数的实际类型,无需显式传参,但依赖Python版本和运行时类型上下文。

from typing import TypeVar, Generic, get_args

class BaseParams(object):
     def __init__(self) -> None:
          self.name = 'set-in-base-class'

class ChildParams(BaseParams):
     def __init__(self) -> None:
          super().__init__()
          self.name = 'set-in-child-class'

R = TypeVar('R', bound=BaseParams)

class MyGeneric(Generic[R]):
     def __init__(self) -> None:
          # 提取泛型参数对应的实际类
          self.r_type = get_args(self.__orig_class__)[0]
     def test(self):
          r = self.r_type()
          print(r.name)

# 使用示例
c = MyGeneric[ChildParams]()
c.test()  # 输出: set-in-child-class

补充说明

  • Python没有C#那样的new()约束语法,无法在类型提示层面强制R有无参构造函数,需要开发者自行保证传入的类可以无参实例化。
  • 方案一兼容性更强,适合大多数场景;方案二虽省去传参步骤,但在子类继承泛型类、类型被封装等场景下可能无法正确获取类型信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 09:52:39