在任何地方使用 `from __future__ import annotations` 有哪些缺点?

16

根据PEP 563,似乎应该会有轻微的性能提升,因为它解决了:

类型提示在模块导入时执行,这不是计算上免费的。

那么...我是否应该在我的软件包中的每个文件中都包含from __future__ import annotations,或者有没有任何理由将其从某些文件中排除?

1个回答

11
TLDR: 一些东西无法使用from __future__ import annotations。由于Python的未来版本将使延迟评估成为强制性,因此为了实现向前兼容,代码不应依赖于即时评估。

由于from __future__ import annotations避免了类型提示的评估,任何依赖于已评估类型提示的内容必须显式评估类型提示。除非显式处理locals,否则通常无法在顶级模块或类范围之外进行此操作。

例如,如果注释评估被延迟,functools.singledispatch无法在函数内部使用类型提示:

from __future__ import annotations
from typing import Type
from functools import singledispatch

def non_global_sdp(local_type: Type):
    @singledispatch
    def default(arg): print("default")

    @default.register
    def case_a(arg: local_type): print("case_a")

    return default

cases = non_global_sdp(int)  # NameError: name 'local_type' is not defined

“延迟评估注释”和“强制引入版本”的确切语义仍未确定。在当前的提案中,from __future__ import annotations的功能最为严格;任何必须与Python的未来版本一起使用的代码都应该使用from __future__ import annotations以避免对即时评估的隐藏依赖。

__future__ — 未来声明定义(Python 3.11)

[1] from __future__ import annotations曾计划在Python 3.10中成为强制性内容,但是Python Steering Council两次决定推迟更改(Python 3.10的公告; Python 3.11的公告)。目前还没有最终决定。另请参阅PEP 563和PEP 649。


也许答案在这里可以更明确一些:有些东西无法与__future__ import annotations一起使用。 - Janosh
1
你的回答不清楚 from __future__ import annotations 是好还是坏。这是一个好的默认设置,对吗?"代码力求向前兼容不应该依赖于第一时间的评估"在实践中意味着什么? - Marcos Pereira
2
@MarcosPereira "...是好还是坏"。这不是问题,而且更为复杂。"在实践中,“...”是什么意思?"它的意思就是答案结尾所说的:"任何必须与Python未来版本一起工作的代码都应该使用from __future__ import annotations来避免对提示评估的隐藏依赖。"。 - MisterMiyagi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接