python - 在带有类型提示的 Python 类外部方法中声明的实例变量

标签 python

我正在努力了解 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/

相关文章:

python - alpha-beta剪枝算法中的alpha值是如何使用和更新的?

python - 从 requirements.txt 安装时出现 "No module named numpy"错误

python - 需要帮助理解这个 Python Viterbi 算法

python - 当数据类型为对象时求列的平均值

python - 如何转换文件以通过 JSON 发送(到 Odoo Controller )

Python plist 解析器 IOError : [Errno 63] File name too long:

python - 如何根据分割图对图像进行模糊处理

python - 在一个应用程序中同时使用 Python3 和 Python2.7

python - MySQL (python 3.6) - SELECT * FROM table - 返回行数而不是表数

python - 使用 Selenium 和 Python 从头开始​​使用 while 循环连接超时