您是否应该在 python 中将类型注释用引号括起来
Should you put quotes around type annotations in python
这两个函数有什么区别?我见过人们在类型注释周围加上引号,有时则将它们省略,但我找不到人们选择使用其中一个的原因。
def do_something(entity: Entity):
pass
def do_something(entity: 'Entity'):
pass
这些有优点或缺点吗?
根据 PEP 484 制作 Forward Reference 时,在类型提示周围加上引号是有意义的。在这种情况下,在名称周围放置引号用于抑制可能发生的 NameError。
在其他情况下,不要使用引号,它不会导致您想要的提示:
>>> def bad_foo(a: 'int'):
... pass
>>> def good_foo(a: int):
... pass
>>> bad_foo.__annotations__['a'] == good_foo.__annotations__['a']
False
虽然目前类型检查器(mypy、atleast)似乎并没有区别对待这些,但我不确定将来是否会出现这种情况。最好清楚,当您实际上不需要引号时不要使用引号。
显然,如果您在某些情况下不引用它们,它也会导致运行时异常。参见 this comment。我不知道为什么,但确实如此:
~ 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
...
>>>
但是您可以使用 from __future__ import annotations
.
来避免它
这两个函数有什么区别?我见过人们在类型注释周围加上引号,有时则将它们省略,但我找不到人们选择使用其中一个的原因。
def do_something(entity: Entity):
pass
def do_something(entity: 'Entity'):
pass
这些有优点或缺点吗?
根据 PEP 484 制作 Forward Reference 时,在类型提示周围加上引号是有意义的。在这种情况下,在名称周围放置引号用于抑制可能发生的 NameError。
在其他情况下,不要使用引号,它不会导致您想要的提示:
>>> def bad_foo(a: 'int'):
... pass
>>> def good_foo(a: int):
... pass
>>> bad_foo.__annotations__['a'] == good_foo.__annotations__['a']
False
虽然目前类型检查器(mypy、atleast)似乎并没有区别对待这些,但我不确定将来是否会出现这种情况。最好清楚,当您实际上不需要引号时不要使用引号。
显然,如果您在某些情况下不引用它们,它也会导致运行时异常。参见 this comment。我不知道为什么,但确实如此:
~ 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
...
>>>
但是您可以使用 from __future__ import annotations
.