深入理解python面向对象中类的内部管理
本文将向你解释python如何存储属性以及如何查找这些属性,阅读本文时,要求你已经对面向对象有了一定的了解
1. 一个简单的类
我定义了一个简单的类
class AirVehicle(object): |
name是实例属性,而category是类属性,在使用过程中,很容易由于理解不清导致一些奇怪的问题
1.1 通过类修改category
p1 = AirVehicle('歼20') |
程序输出结果
飞机 飞机 |
通过类修改category以后,对所有实例都生效了,那么通过实例进行修改是否也可以呢?
1.2 通过实例修改category
p1 = AirVehicle('歼20') |
程序输出结果
飞机 飞机 |
通过实例p1修改category属性,只对p1生效了,p2的category属性仍然是飞机,想要搞清楚这种差别,就需要探究python是如何存储实例属性和类属性的
2. python如何存储实例属性
python中,实例属性存储在一个字典(dict)中,对于属性的操作,都是在操作这个字典
p1 = AirVehicle('歼20') |
程序输出结果
{'name': '歼20'} |
你甚至可以直接操作这个字典
p1 = AirVehicle('歼20') |
3. python如何存储类属性
同样是存储在字典中,只是这个字典是类的字典
print(AirVehicle.__dict__) |
程序输出结果
{'__module__': '__main__', 'category': '飞机', '__init__': <function AirVehicle.__init__ at 0x103eefd90>, |
这次输出的信息比较多,我们只关注category和fly,类的属性和方法存在在类的__dict__之中
4. 属性寻找规则
在实例p1中,是没有category这个属性的,当解释器在p1的__dict__找不到category时,就会去类AirVehicle的__dict__查找,找到后返回。
当你执行p1.category = ‘战斗机’时,修改的是p1的__dict__, 而类AirVehicle的__dict__则并没有被修改,因此再次执行print(p1.category, p2.category)时,p1的category是战斗机, 而p2的category还是飞机,因为p2的__dict__中仍然没有category这个key,还是要到AirVehicle中寻找。