即使我使用 TYPE_CHECKING import,也会获取 NameError 进行注释

Getting NameError for annotation even if I use TYPE_CHECKING import

我有两个 class 带有注释/类型提示。

第一个没有任何问题:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from bunyamin.models.exchange import Exchange

class Kline:

    def read_klines(exchange: Exchange):
        pass

第二个真的很像:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from bunyamin.models.timeframe import Timeframe

def normalize_dt(dt: datetime, timeframe: Timeframe) -> datetime:  # -> This line raises NameError
    pass

但加注 NameError: name 'Timeframe' is not defined.

我知道我可以只使用一个字符串(如 'Timeframe')而不是 class 本身,但据我所知,这不是预期的行为。我错过了什么?

Python 我使用的版本是 3.8.2,如果相关的话。

编辑:

虽然我试图找出问题所在,但我省略了所有“看似 不相关”的导入。但是第一个文件实际上在顶部包含 from __future__ import annotations,这使得它可以工作。详情见第一个回答。

我明白了。

为了隔离问题,我在两个 classes 上都省略了“看似”不相关的导入。但我刚刚注意到,在包含 Kline class 的第一个文件中,我使用了 from __future__ import annotations,而在第二个文件中我没有使用,这推迟了对注释的评估。

可在此处找到参考资料:

https://www.python.org/dev/peps/pep-0563/

注意 from __future__ import annotations 必须出现在文件的顶部,否则会引发 SyntaxError

当您使用 TYPE_CHECKING 常量时,函数参数注释必须用引号括起来,使其成为“前向引用”,以便在运行时对解释器隐藏它,如 timeframe: 'Timeframe'。因为这些默认情况下是在函数定义时计算的,直到 Python 3.10,当注释的延迟计算成为默认值时。