3 回答

TA贡献1775条经验 获得超8个赞
简单地说,你就是做不到。
正如文档中所述,
可以使用具有多个槽父类的多重继承,但只允许一个父类具有由槽创建的属性(其他基类必须具有空槽布局) - 违规会引发 TypeError。
背后的想法__slots__是为实例的内存布局中的每个属性保留特定的插槽。A并且B试图为slot1和slot2属性保留相同的内存布局部分,并且C不能为两个属性保留相同的内存。它只是不兼容。
感谢评论中提到的 JCode,修改以下方法为正确。
但是总有办法,我个人更喜欢__slots__在有多个继承类时使用包含所有必需插槽的公共基类。
import pympler.asizeof
class base():
__slots__ = ['a','b']
class A(base):
__slots__ = []
class B(base):
__slots__ = []
class C(A,B):
__slots__ = []
class D():
pass
#Update
bb = base()
bb.a = 100
bb.b = 100
print(pympler.asizeof.asizeof(bb))
a = A()
a.a = 100
a.b = 100
print(pympler.asizeof.asizeof(a))
c = C()
c.a = 100
c.b = 100
print(pympler.asizeof.asizeof(c))
d = D()
d.a = 100
d.b = 100
print(pympler.asizeof.asizeof(d))
更新 4 个值将是 88、88、88、312。虽然__slots__保留。

TA贡献1876条经验 获得超5个赞
对于带槽的类使用多重继承,一种实用的选择是只有一个父类具有非空槽。其余的类然后用作具有定义(但为空)插槽的“混合”。然后,在子类中,根据需要简单地定义最终插槽。
如前所述,当所有父项都定义非空槽时,多重继承是有问题的。
>>> class B: __slots__ = ('a', 'b')
...
>>> class C: __slots__ = ('a', 'b')
...
>>> class D(C, B): __slots__ = ('a', 'b')
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: multiple bases have instance lay-out conflict
>>> class D(C, B): __slots__ = ('a', 'b', 'c')
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: multiple bases have instance lay-out conflict
这里建议的方法构成C一个定义空槽的“mixin”类。然后子类使用多重继承,可以简单地将插槽定义为所需的任何内容。
>>> class B: __slots__ = ('a', 'b')
...
>>> class C: __slots__ = ()
...
>>> class D(C, B): __slots__ = ('a', 'b')
...
>>> class D(C, B): __slots__ = ('a', 'b', 'c')
...
添加回答
举报