【发布时间】:2018-09-04 18:18:47
【问题描述】:
在 PEP 563 中,from __future__ import annotations 更改了类型注释,以便对其进行延迟评估,这提供了很多好处,例如前向引用。
但是,这似乎与其他功能(如数据类)搭配得不好。例如,我有一些代码检查类的__init__ 方法的类型参数。 (真正的用例是为类提供一个默认的序列化器,但这在这里并不重要。)
from dataclasses import dataclass
from typing import get_type_hints
class Foo:
pass
@dataclass
class Bar:
foo: Foo
print(get_type_hints(Bar.__init__))
在 Python 3.6 和 3.7 中,这符合预期;它打印{'foo': <class '__main__.Foo'>, 'return': <class 'NoneType'>}。
但是,如果在 Python 3.7 中,我添加了from __future__ import annotations,那么这将失败并出现错误:
NameError: name 'Foo' is not defined
我想我明白为什么会这样。 __init__ 方法在 dataclasses 中定义,它的环境中没有 Foo 对象,并且 Foo 注释被传递给 dataclass 并附加到 __init__ 作为字符串 "Foo" 而不是与原始对象 Foo 相比,但新注释的 get_type_hints 仅在定义 __init__ 的模块中进行名称查找,而不是定义注释的位置。
我觉得我一定做错了什么。我很惊讶这两个新功能一起玩得这么差。是否有适当的方法来检查 __init__ 方法的类型提示,以便它像在普通类上一样在数据类上工作?
【问题讨论】:
-
get_type_hints(Bar)似乎工作正常,尽管它没有return注释。它给了我{'foo': <class '__main__.Foo'>} -
@PatrickHaugh 是的,但
get_type_hints(Bar)不是我想要的。我的用例是一个检查,它接受一个类并查看该类的__init__方法。如果Bar不是数据类,那么get_type_hints(Bar)将不起作用。如果数据类Bar的字段是init=False,那么它也不起作用。
标签: python annotations python-3.7 python-dataclasses