python - 为什么类属性并不总是作为键出现在实例的字典中?
问题描述
我在关于属性的这一部分中阅读了有关 Python 中的 OOP 的内容,并且对下面的示例感到震惊。
我不明白为什么实例的字典(class
赋予新属性)为空:
class Robot(object):
pass
x = Robot()
Robot.brand = "Kuka"
x.brand
输出:
'Kuka'
x.brand = "Thales"
Robot.brand
输出:
'Kuka'
y = Robot()
y.brand
输出:
'Kuka'
Robot.brand = "Thales"
y.brand
输出:
'Thales'
x.brand
输出:
'Thales'
如果你查看__dict__
字典,你可以看到发生了什么:
x.__dict__
输出:
{'brand': 'Thales'}
y.__dict__
输出:
{}
来自同一网站的另一句话:
如果您尝试访问 y.brand,Python 会首先检查“brand”是否是 y 的键。
__dict__
字典。如果不是,Python 会检查“品牌”是否是机器人的键。__dict__
. 如果是这样,则可以检索该值。
我的问题是:为什么要y.__dict__
给出一个空字典?其背后的逻辑和机制是什么?
解决方案
我们可以用它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 将查找brand
in x.__dict__
,什么也没有,所以它会去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 会查找brand
in y.__dict__
,但什么也没找到,然后去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
。我们可以检查 idy.brand
是否与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
推荐阅读
- excel - 未知表中的范围
- wordpress - 按订单获取付款类型
- python - 在 py.test 中捕获异常并引发错误时抑制第一个异常
- javascript - 在 Vue.js 手表中动画 css 属性,性能问题
- javascript - JSON 解析器如何编码不在基本多语言平面中的 unicode 字符?
- java - java中的平方应用
- java - Spring批量将资源的值从步骤1传递到下一步
- html - 如何禁用滚动并让网站适应屏幕而不移动。
- google-apps-script - 电子表格副本中的 Google 脚本不执行
- javascript - Puppeteer 从 pdf 下载链接获得响应