如何访问 typing.Generic 的类型参数?

新手上路,请多包涵

typing 模块为通用类型提示提供了一个基类: typing.Generic 类。

Generic 的子类接受方括号中的类型参数,例如:

 list_of_ints = typing.List[int]
str_to_bool_dict = typing.Dict[str, bool]


我的问题是,如何访问这些类型参数?

也就是说,给定 str_to_bool_dict 作为输入,我怎样才能得到 strbool 作为输出?

基本上我正在寻找这样的功能

>>> magic_function(str_to_bool_dict)
(<class 'str'>, <class 'bool'>)

原文由 Aran-Fey 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 926
2 个回答

Python >= 3.8

从 Python3.8 开始,有 typing.get_args

 print( get_args( List[int] ) ) # (<class 'int'>,)

PEP-560 还提供了 __orig_bases__[n] ,它允许我们使用第 n 个通用基础的参数:

 from typing import TypeVar, Generic, get_args

T = TypeVar( "T" )

class Base( Generic[T] ):
    pass

class Derived( Base[int] ):
    pass

print( get_args( Derived.__orig_bases__[0] ) ) # (<class 'int'>,)


Python >= 3.6

从 Python 3.6 开始。有一个公共 __args__ 和 ( __parameters__ ) 字段。例如:

 print( typing.List[int].__args__ )

这包含通用参数(即 int ),而 __parameters__ 包含通用参数本身(即 ~T )。


Python < 3.6

使用 typing_inspect.getargs


一些注意事项

typing 遵循 PEP8 。 PEP8 和 typing 均由 Guido van Rossum 合着。前后双下划线定义为: “存在于 用户控制的名称空间 中的“魔法”对象或属性”

dunders 也在线评论;从官方 打字 库中我们可以看到:

  • __args__ 是下标中使用的所有参数的元组,例如 Dict[T, int].__args__ == (T, int) ”。

但是, 作者还指出

  • “打字模块具有临时状态,因此它不在向后兼容性的高标准范围内(尽管我们尽量保持它),对于(尚未记录的)dunder 属性尤其如此 __union_params__ 。如果您想在运行时上下文中使用键入类型,那么您可能会对 typing_inspect 项目感兴趣(其中一部分可能会在稍后键入)。”

我一般来说,无论你用 typing 做什么,都需要暂时保持最新。如果您需要向前兼容的更改,我建议您编写自己的注释类。

原文由 c z 发布,翻译遵循 CC BY-SA 4.0 许可协议

据我所知,这里没有令人满意的答案。

我想到的是存储此信息的 __args__ 未记录的属性:

 list_of_ints.__args__
>>>(<class 'int'>,)

str_to_bool_dict.__args__
>>>(<class 'str'>, <class 'bool'>)

但在 typing 模块的文档中没有提及它。

值得注意的是,它 非常接近于在文档中被提及

也许我们还应该讨论是否需要记录 GenericMeta.__new__ 的所有关键字参数。 There are tvars , args , origin , extra , and orig_bases .我想我们可以说说前三个(它们对应于 __parameters____args____origin__ 并且这些在打字中被使用)。

它并没有完全成功

我添加了 GenericMeta __all__ 添加了docstrings docstrings to GenericMeta and GenericMeta.__new__ .我决定不描述 __origin__ 和文档字符串中的朋友。相反,我只是在第一次使用它们的地方添加了注释。

从那里,您仍然有三个非相互排斥的选项:

  • 等待 typing 模块完全成熟,希望这些功能能尽快被记录下来

  • 加入 Python ideas 邮件列表,看看是否可以收集到足够的支持来使这些内部结构公开/成为 API 的一部分

  • 同时处理未记录的内部结构,打赌不会对这些内部结构进行更改,或者更改很小。

请注意,第三点几乎无法避免,因为即使是 API 也可能会发生变化

typing 模块已临时包含在标准库中。 如果核心开发人员认为有必要,甚至可以在次要版本之间添加新功能和更改 API

原文由 Jacques Gaudin 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题