我想使用typing.get_type_hints作为带有list[str]注释的数据集。
# python3.8
from __future__ import annotations # Enable PEP585 for Python3.8
import typing
from dataclasses import dataclass
@dataclass
class Foo:
a: list[int]
print(typing.get_type_hints(Foo))但是,此代码会引发一个错误:
File "foo.py", line 11, in <module>
print(typing.get_type_hints(Foo))
TypeError: 'type' object is not subscriptable引发此异常是因为python3.8不支持运行时list[str]评估。在python3.8中是否有使用此功能的另一种方法?或者,如果我在python3.8中使用PEP585,它是否完全无法获取类型信息?
注意:
list[str]行中发生,而是在typing.get_type_hints中发生。list[str],我们可以使用from __future__ import annotations注释。发布于 2021-02-02 10:13:44
让我们考虑以下示例,因为数据类型与此行为无关:
class Foo:
bar: list[str]在Python < 3.9中,这将导致以下错误:
Traceback (most recent call last):
File "main.py", line 1, in <module>
class Foo:
File "main.py", line 2, in Foo
bar: list[str]
TypeError: 'type' object is not subscriptable如果我们添加from __future__ import annotations,所做的(每个佩普563)就是将注释存储为字符串,以供以后的评估:
...function和变量注释将不再在定义时进行计算。相反,字符串形式将保留在相应的
__annotations__字典中。
如果我们添加该导入,类定义不会出错,我们可以看到在__annotations__中以原始形式存储了哪些注释
>>> Foo.__annotations__
{'bar': 'list[str]'}这就是佩普585所说的意思:
从Python3.7开始,当使用
from __future__ import annotations时,函数和变量注释可以直接参数化标准集合。
因为注释是作为字符串存储的,所以list[str]不会在3.7和3.8中实际运行这一事实并不是一个问题。它确实是而不是,这意味着标准集合本身可以通过这种方式进行索引,实际上,它继续添加:
此语法在PEP 585之前的用途是有限的。类型别名或类型转换等类型的某些特性要求在运行时上下文中将类型置于注释之外。
那么,我们什么时候将'list[str]'引入运行时上下文呢?typing.get_type_hints所做的工作包括:
以字符串形式编码的...forward引用是通过在
globals和locals命名空间中计算它们来处理的。
这就是为什么您的示例中的错误来自于print(typing.get_type_hints(Foo)),而不是类的定义--这就是延迟的计算发生的时候。
简而言之,无法使用get_type_hints或任何其他对注释进行评估的方法,除非:
typing.List而不是内置list;或在这两种情况下,不再需要__future__导入(除非其他注释需要延迟的评估行为)。
https://stackoverflow.com/questions/66006087
复制相似问题