gpt4 book ai didi

python - dataclasses.Field 不将类型注释解析为实际类型

转载 作者:行者123 更新时间:2023-12-05 08:52:39 25 4
gpt4 key购买 nike

Field 的文档python 标准类 dataclasses模块仅指定:

Its documented attributes are:

  • [...]
  • type: The type of the field.

对我来说,这似乎意味着字段将包含类型本身,而不仅仅是字符串形式的名称。

但是,它似乎只是简单地照原样复制了类型注释,这使得它毫无用处。

例子:

@dataclasses.dataclass 
class C:
c: 'C'

dataclasses.fields(C)[0].type # This returns the string 'C'
typing.get_type_hints(C)['c'] # This returns the class C, as expected

问题甚至在使用PEP563 时系统地发生类型注解。

这是数据类模块中的错误吗?这是预期的行为吗?如果是这样,我如何在给定 Field 实例的情况下检索类型对象?

最佳答案

这是故意的。在导入时解析类型提示代价高昂,尤其是当 from __future__ import annotations 一开始就禁用解析它们时。

最初,当您使用 from __future__ import annotations 开关并包含 ClassVar 时,将 PEP 563 添加到 Python 3.7 会破坏数据类。或 InitVar字段的类型注释;这些不会在这一点上得到解决,仍然是一个字符串。如果您明确使用字符串,这在 PEP 563 之前就已经是一个问题,请参阅 dataclasses issue #92 .这变成了 Python bug, #33453 ,一旦数据类将其纳入 Python 3.7 中。

“父”项目 attrs 启发了 dataclassesalso had this issue to solve .在那里,Łukasz Langa(大多数类型提示 peps 的合著者,包括 PEP 563)指出:

OK, so I tried the above and it seems it's a nuclear option since it forces all annotations to be evaluated. This is what I wanted to avoid with from __future__ import annotations.

并且在 discussion on the pull request that fixed issue 33453 dataclasses 的作者 Eric Smith 表示:

I've been researching doing just that. I think @ambv's point is that it introduces a performance hit due to calling eval on every field, while the point of string annotations is to remove a performance hit.

此外,还有其他问题;您不能在导入时评估所有类型提示,而不是在它们使用前向引用时:

In addition to the performance issue, in the following case (without a __future__ statement and without dataclasses), I get an error on get_type_hints() because C is undefined when get_type_hints() is called. This is python/typing#508. Notice that where get_type_hints() is called in this example is exactly where @dataclass is going to run and would need to call the stripped down get_type_hints().

所以最后,dataclasses 所做的只是将字符串试探法应用于注释,而不会为您加载它们。

要检索类型,只需在类本身上使用 get_type_hints(),并将字段 .name 属性作为结果的键:

resolved = typing.get_type_hints(C)
f = dataclasses.fields(C)[0]
ftype = resolved[f.name]

关于python - dataclasses.Field 不将类型注释解析为实际类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55937859/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com