<p>这是类变量和实例变量的正常相互作用。它与打字无关</p>
<pre><code>class Quux:
foo = 1
bar = 2
def __init__(self):
self.bar = 3
self.baz = 4
quux = Quux()
Quux.foo # => 1 - class variable
Quux.bar # => 2 - class variable
quux.foo # => 1 - class variable, because no instance variable
quux.bar # => 3 - instance variable shadowing the class variable
quux.baz # => 4 - instance variable
</code></pre>
<p>您的错误是这里的措辞:</p>
<pre><code>captain: str = 'Picard' # instance variable with default
</code></pre>
<p><code>captain</code>不是此处的实例变量。这定义了一个类变量,当未设置相应的实例变量时,该类变量作为默认值。但是类变量和实例变量是两个独立的东西</p>
<p>请注意,类型仅由静态类型检查器进行计算,而不是由Python解释器本身进行计算。因此,这两者之间不存在任何运行时语义差异:</p>
<pre><code>class CheckedQuux:
foo: Dict[str, int] = {}
bar: ClassVar[Dict[str, int]] = {}
</code></pre>
<p>在运行时,它们都是空字典对类变量的赋值。如果注释使其中一个定义了实例变量,而另一个定义了类变量,则会违反键入不能具有运行时效果的规则。<code>ClassVar</code>下的注释具有误导性,尽管文本给出了关于其含义的提示:注释用于指示变量将如何使用的<em>意图</em>。类型检查器假设上面的<code>foo</code>将从实例(<code>checked_quux.foo</code>)访问,并且可能会被实例变量覆盖,而<code>bar</code>不应在实例上访问,而应仅在类(<code>CheckedQuux.bar</code>)上访问,如果我们试图在实例(<code>checked_quux.bar</code>)上访问它,则应引发类型检查错误</p>