即使我使用 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,当注释的延迟计算成为默认值时。
我有两个 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,当注释的延迟计算成为默认值时。