Python多继承与内存分配:子类实例创建时的内存分配规则问询
咱们先把结论摆出来:当你创建X的实例x时,Python根本不会为任何基类的variable属性分配新内存——因为这些属性早在对应的类(O、A、B)被定义的时候,就已经存储在类对象自己的命名空间里了。MRO(方法解析顺序)的作用只是帮你查找属性,而不是决定内存分配。
下面拆解细节说清楚:
类属性的本质:属于类,而非实例
你代码里定义的variable都是类属性,它们是绑定在类本身的,不是绑定在实例上。比如O.variable在class O被执行的时候就已经在内存里了,A.variable、B.variable同理。X因为没自己定义variable,所以它的这个属性只是"指向"了MRO链中第一个找到的variable(也就是A的那个),但X类本身也没有新建这个属性的内存空间。实例
x的内存里装了什么?
创建x = X()时,实例x的内存默认是空的(你可以打印x.__dict__看看,输出是{})。只有当你给x的实例属性赋值时(比如x.variable = 42),Python才会在x的实例命名空间里分配内存,存储这个属于实例自己的variable值——这时候再访问x.variable就会优先取实例自己的,而不是类的。MRO的真实作用
MRO是Python在你访问x.variable时的查找顺序:它会按照X → A → B → O的顺序去各个类的命名空间里找variable这个属性。但这只是"查找"已存在的属性,不是"分配"新内存。换句话说,MRO决定的是你拿到哪个已有的属性值,而不是要不要为实例创建这个属性。
可以用这段代码验证一下:
# 验证实例的__dict__是空的 x = X() print(x.__dict__) # 输出: {} # 访问x.variable其实是查找A类的variable print(x.variable) # 输出: abcdef # 给实例赋值后,实例才有自己的variable x.variable = 42 print(x.__dict__) # 输出: {'variable': 42} print(x.variable) # 输出: 42 # 类的属性不受实例赋值影响 print(A.variable) # 输出: abcdef
内容的提问来源于stack exchange,提问作者Ocemagnuf Nimda

