Python3.6.5当类的多重继承具有u槽时,“多个基有实例布局冲突”__

2024-09-25 02:37:00 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我运行这个代码,就会得到主题错误消息。但为什么呢?以及如何避免它得到C类的父插槽?在

class A():
        __slots__ = ['slot1']

class B():
        __slots__ = ['slot2']

class C(A, B):
        __slots__ = []

Tags: 代码消息主题错误class插槽slotsslot1
2条回答

简单地说,你就是做不到。在

Documentation所述

Multiple inheritance with multiple slotted parent classes can be used, but only one parent is allowed to have attributes created by slots (the other bases must have empty slot layouts) - violations raise TypeError.

__slots__背后的思想是为实例的内存布局中的每个属性保留特定的插槽。^这两个


感谢注释中所述的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__保留。在

在我看来,这是一个愚蠢的变通办法。 这就是为什么当__slots__为空时不会引发TypeError,而拥有一个空的__slots__属性会保留python的“奇怪”行为,即在分配给__slots__中未定义的属性时会发出警告。在

因此,考虑以下元类

class SlotBase(type):
    def __new__(cls,name,bases,dctn):
        if ('_slots_' in dctn) and not ('__slots__' in dctn):
            dctn['__slots__'] = []
        elif '__slots__' in dctn:
            for base in bases:
                if hasattr(base,'_slots_'):
                    dctn['__slots__'] += getattr(base,'_slots_')
        return super().__new__(cls,name,bases,dctn)

然后在基类上部署。在

^{pr2}$

如果我们执行以下代码

c=C()
c.classPropertyC
c.classPropertyA
c.functA()
c.functB()
c.slot1='Slot exists then assignment is accepted'
c.slot3='Slot does not exists then assignment couldn\'t be accepted'

这将产生以下输出

Just another silly value
Some silly value
I'm functA
I'm functB
Traceback (most recent call last):
  File "/tmp/slots.py", line 41, in <module>
    c.slot3='Slot does not exists then assignment couldn\'t be accepted'
AttributeError: 'C' object has no attribute 'slot3'

相关问题 更多 >