声明但未实例化的类变量

问题描述

我正在尝试理解以下Python代码

class MyClass():
    aa:int
    

这是怎么回事?在我看来,变量aa一个已声明但未初始化的类变量:int似乎是一个键入提示。我对么?我可以实例化该类,但无法访问aa。这使我认为我的理解是错误的。见下文

 mm = MyClass()
 mm.aa
Traceback (most recent call last):

  File "<ipython-input-15-cfce603dd5e0>",line 1,in <module>
    mm.aa

AttributeError: 'MyClass' object has no attribute 'aa'

解决方法

实际上,这只会为属性创建annotation,而不会创建属性本身。属性和变量仅通过赋值创建,此处未赋值,因此不存在(即使使用隐式None也不存在)。

如果属性在__init__之外初始化,例如:

,此模式对于满足类型检查器很有用。
class MyClass(SomeParentClass):
    aa: int

    def initialize(self):
        self.aa = 'foo'

假设SomeParentClass将在实例化过程中的某个定义点调用initialize,它希望子类使用initialize进行初始化,而不是覆盖__init__ 。类型检查器可能会在这里抱怨aa是在__init__之外创建的,因此不安全。 aa: int注释明确指出,aa应该在任何时候都以int的形式存在,因此可以安全访问(请注意,实际上您的责任)。例如,可以在Tornado中找到这种模式的示例。

当然,这些注释的另一种用法是在运行时显式使用这些注释的类,就像Python自己的dataclasses一样。