我正在努力了解 Python 变量注释。根据 PEP-0526,我们现在有这样的内容:
class BasicStarship:
captain: str = 'Picard' # instance variable with default
damage: int # instance variable without default
stats: ClassVar[Dict[str, int]] = {} # class variable
这是一个艰难的周末,我的 Python 有点生疏了,但我认为未分配给 self 的声明变量是类变量。以下是一些有趣的例子:
class BasicStarship:
captain: str = 'Picard' # instance variable with default
def __init__(self,name):
self.captain = name
wtf = BasicStarship('Jim')
BasicStarship.captain = 'nope'
print(wtf.captain) #=> Jim
上面的代码按照我的预期工作。然而下面让我有点困惑。
class BasicStarship:
captain: str = 'Picard' # instance variable with default
wtf = BasicStarship()
BasicStarship.captain = 'nope'
print(wtf.captain) #=> 'nope'
我希望在第二个示例中出现“Picard”而不是“nope”。我觉得我缺少一些关于类变量与实例变量的规则。在某种程度上,我认为执行 BasicStarship.captain
会导致类错误,因为 captain
是一个实例变量(在第一个示例中,在第二个示例中不确定)例子)。您是否始终能够在类声明之后(在方法之外)定义实例变量?类和实例变量之间是否存在某种相互作用可以使这一点更清楚?
使用 Python 3.6.3 运行代码
最佳答案
我分享了您对文档的一些困惑,因为似乎 captain
在您的示例中是类属性而不是实例属性。
考虑一下:
class BasicStarship:
captain = 'Picard'
def __init__(self, captain=None):
if captain:
self.captain = captain
wtf1 = BasicStarship()
wtf2 = BasicStarship('Me!')
BasicStarship.captain = 'Riker'
print(wtf1.captain)
print(wtf2.captain)
正如您所期望的(根据您的问题),这将打印:
Riker
Me!
但是,这很有趣:
print(wtf1.__dict__)
print(wtf2.__dict__)
print(BasicStarship.__dict__)
结果:
{}
{'captain': 'Me!'}
{'__module__': '__main__', 'captain': 'Riker', '__init__': <etc.> }
所以,wtf1
没有名为 captain
的属性因此使用名为 captain
的类属性(解释了为什么当你改变它时它会改变)。 wtf2
确实有一个名为 captain
的属性,这样就覆盖了类属性。 BasicStarship
显示类属性。
这一切都有意义,并且与实际文档中给出的示例类似,唯一令人困惑的部分是描述为 instance variable with default
,因为它似乎更正确为 class variable with default
.
(在 Python 3.7.5 上,其他相同)
关于python - 在带有类型提示的 Python 类外部方法中声明的实例变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59606282/