我们可以使用id(<object>) 来检查发生了什么。
声明一个新的空类Robot
class Robot(object):
... pass
...
Robot
<class '__main__.Robot'>
Robot.__dict__
mappingproxy({'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Robot' objects>, '__weakref__': <attribute '__weakref__' of 'Robot' objects>, '__doc__': None})
Robot 类的新实例
x = Robot()
x
<__main__.Robot object at 0x0000022811C8A978>
x 实例为空
x.__dict__
{}
定义了新的类属性brand
Robot.brand = "Kuka"
Robot.brand
'Kuka'
如果我们尝试访问x.brand,Python 会在x.__dict__ 中查找brand,但什么也找不到,所以它会转到Robot.__dict__ 并找到类属性brand。
x.brand
'Kuka'
我们可以验证我们实际上看到的是相同的
id(Robot.brand)
2371120205752
id(x.brand)
2371120205752
定义了新的实例属性brand
x.brand = "Thales"
并且类属性brand 保持不变
Robot.brand
'Kuka'
我们可以验证我们实际上看到了两个不同的属性
id(x.brand)
2371119992200
id(Robot.brand)
2371120205752
新实例 y 已创建并且为空
y = Robot()
y.__dict__
{}
我们可以验证这是一个新的:
id(y)
2371119989200
如果我们尝试访问y.brand,Python 将在y.__dict__ 中寻找brand,但什么也没找到,然后转到Robot.__dict__ 并找到类属性brand。
y.brand
'Kuka'
我们可以验证 id 是否与Robot.brand 相同。所以y是对Robot.brand的引用
id(y.brand)
2371120205752
如果我们修改类属性brand
Robot.brand = "Thales"
id(Robot.brand)
2371119992200
y.brand 被修改,因为此时不是实例属性,而是对类属性Robot.brand 的引用。我们可以检查y.brand的id是否与Robot.brand相同。
y.brand
'Thales'
id(y.brand)
2371119992200
现在我们可以检查x 有一个实例属性x.brand
x.brand
'Thales'
x.__dict__
{'brand': 'Thales'}
但是 y 什么都没有,因为它只是对 Robot.brand 的引用
y.__dict__
{}
Robot.brand 具有类属性 brand,其值为 Thales
Robot.__dict__
mappingproxy({'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Robot' objects>, '__weakref__': <attribute '__weakref__' of 'Robot' objects>, '__doc__': None, 'brand': 'Thales'})
在此处查看其他说明:https://github.com/leocjj/0123/blob/master/Python/0123P_9_Classes_objects.txt