如何解决如何在 Python3.8 中将 `typing.get_type_hints` 与 PEP585 一起使用?
我想将 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
注释。
解决方法
让我们考虑以下示例,因为数据类与此行为无关:
class Foo:
bar: list[str]
在 Python
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
,那么(每个 PEP 563)所做的就是将注释存储为字符串,以供以后评估:
...函数和变量注释将不再在
定义时间。相反,字符串形式将保留在
相应的 __annotations__
字典。
如果我们添加该导入,类定义不会出错,我们可以看到哪些注释以原始形式存储在 __annotations__
中:
>>> Foo.__annotations__
{'bar': 'list[str]'}
这就是 PEP 585 的意思:
从 Python 3.7 开始,当 from __future__ import annotations
为
使用,函数和变量注释可以参数化标准
直接收藏。
由于注释存储为字符串,因此 list[str]
实际上不会在 3.7 和 3.8 中运行这一事实不成问题。它不意味着标准集合本身可以以这种方式索引,实际上它继续添加:
此语法在 PEP 585 之前的用处是有限的……某些 类型别名或强制转换等打字功能需要放置类型 在注释之外,在运行时上下文中。
那么我们什么时候将 'list[str]'
带入运行时上下文? typing.get_type_hints
的作用包括:
... 编码为字符串文字的前向引用由
在 globals
和 locals
命名空间中评估它们。
这就是为什么您的示例中的错误来自 print(typing.get_type_hints(Foo))
,不是 类的定义 - 那是发生延迟评估的时候。
简而言之,无法使用 get_type_hints
或任何其他评估注释的方法,除非:
- 您使用
typing.List
而不是内置的list
;或 - 您至少升级到 Python 3.9。
无论哪种情况,都不再需要 __future__
导入(除非其他注释需要延迟评估行为)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。