你应该在 python 中的类型注释周围加上引号吗

ret*_*vil 18 python static-typing type-hinting python-3.x

这两个函数有什么区别?我见过人们在类型注释周围加上引号,有时将它们排除在外,但我找不到人们选择使用其中一种的原因。

def do_something(entity: Entity):
    pass
def do_something(entity: 'Entity'):
    pass
Run Code Online (Sandbox Code Playgroud)

这些有什么优点或缺点吗?

Jim*_*ard 11

根据 PEP 484进行前向引用时,在类型提示周围加上引号是有意义的。在这种情况下,在名称周围加上引号用于抑制可能发生的 NameError。

在其他情况下,不要使用引号,它不会导致您想要的提示:

>>> def bad_foo(a: 'int'):
...     pass
>>> def good_foo(a: int):
...     pass
>>> bad_foo.__annotations__['a'] == good_foo.__annotations__['a']
False
Run Code Online (Sandbox Code Playgroud)

尽管现在类型检查器(mypy,至少)似乎并没有区别对待这些,但我不确定将来是否会如此。最好是清楚的,当你实际上不需要它们时不要使用引号。

  • [`typing.get_type_hints`](https://docs.python.org/3/library/typing.html#typing.get_type_hints) 是使用前向引用解析类型提示的方法,如果您需要这样做的话。 (2认同)

Tim*_*mmm 5

显然,如果在某些情况下不引用它们,它也可能导致运行时异常。看到这个评论。我不知道为什么,但确实如此:

 ~ python3
Python 3.9.2 (default, Mar 26 2021, 23:27:12)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def main() -> OrderedDict[str, str]:
...     x: OrderedDict[str, str] = OrderedDict()
...     print(x)
...     return x
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'OrderedDict' is not defined
>>> def main() -> 'OrderedDict[str, str]':
...     x: OrderedDict[str, str] = OrderedDict()
...     print(x)
...     return x
...
>>>
Run Code Online (Sandbox Code Playgroud)

但是您可以通过使用来避免它from __future__ import annotations

  • 代码中的错误消息很容易修复:“from collections import OrderedDict” (2认同)