Python变量和函数注释引发AttributeError
尽管变量current_timestamp(因此也是函数返回值)和变量time是datetime.datetime类对象,但以下代码引发 AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
from datetime import datetime
def current_time() -> datetime.datetime:
current_timestamp: datetime.datetime = datetime.now()
return current_timestamp
time: datetime.datetime = current_time()
print(time)
仅更改函数返回值和time变量的注释即可解决问题。
from datetime import datetime
def current_time() -> datetime:
current_timestamp: datetime.datetime = datetime.now()
return current_timestamp
time: datetime = current_time()
print(time)
谁能解释为什么注释datetime.datetime只为函数返回值和time变量引发 AttributeError而不是为current_timestamp变量引发?
我正在运行 Python 3.8。
回答
来自PEP 526,其中定义了此语法
注释局部变量将导致解释器将其视为局部变量,即使它从未被赋值。不会评估局部变量的注释:
def f(): x: NonexistentName # No error.但是,如果它是在模块或类级别,则类型将被评估:
x: NonexistentName # Error! class X: var: NonexistentName # Error!此外,在模块或类级别,如果被注解的项目是一个简单的名称,那么它和注解将
__annotations__作为从名称到评估注解的有序映射存储在该模块或类的属性中(如果私有则被破坏) .
所以原因是注解是一种通用工具,留下了将它们用于类型签名以外的东西的可能性。在模块或类级别,您可以使用反射技术在运行时访问此信息,因此该值必须存在并且将被评估。然而,当应用于局部变量时,局部变量没有反射可用,因此注释仅对解析代码的第三方工具有用,因此 Python 本身没有理由对其进行评估。
值得注意的是,这mypy将在第二个示例中失败,如果您想使用实际的类型检查器,则必须在每个地方更正注释。