我遇到了这个错误,我真的很想为我的自定义数据库节点使用插槽。这是我制作的测试套件(在 Python 3.x 中):
import logging
A = None, 'attr1', 'attr2', 'attr3', 'attr4'
class C12(object):
__slots__ = (A[1], A[2])
class C1234(object):
__slots__ = (A[1], A[2], A[3], A[4])
class C34(object):
__slots__ = (A[3], A[4])
class C3byC12(C12):
__slots__ = (A[3])
class CEmpty(object):
__slots__ = ()
MSG_FRM = '\n\tc1: {}\n\tc2: {}\n\t__slots__: {}'
NOT_DEF = 'not defined'
def test(c1, c2, slots):
logging.debug('*'*20 + ' new class test ' + '*'*20)
msg = MSG_FRM.format(c1, c2, slots)
try:
if slots == NOT_DEF:
class TestClass(c1, c2): pass
else:
class TestClass(c1, c2):
__slots__ = slots
except TypeError:
logging.exception('BOOM!!! ' + msg)
else:
logging.debug('No Boom! ' + msg)
instance = TestClass()
if '__dict__' in dir(instance):
logging.warning('Instance has __dict__!')
else:
logging.debug('Instance __slots__:{}'.format(
instance.__slots__))
logging.debug('Attributes in instance dir: {}'.format(
' '.join(['X' if (a in dir(instance)) else '_'
for a in A[1:]])))
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
test(C12, C34, (A[2], A[4]))
test(C12, C3byC12, (A[2],))
test(C3byC12, C12, (A[4],))
test(C1234, C34, (A[2], A[4]))
test(C1234, CEmpty, (A[2], A[4]))
test(C12, CEmpty, (A[2], A[4]))
test(C12, CEmpty, (A[1], A[2]))
test(C12, CEmpty, ())
test(CEmpty, C1234, (A[2], A[4]))
test(CEmpty, C12, (A[3],))
test(C12, C34, NOT_DEF)
test(C12, CEmpty, NOT_DEF)
结果如下:
DEBUG:root:******************** new class test ********************
ERROR:root:BOOM!!!
c1: <class '__main__.C12'>
c2: <class '__main__.C34'>
__slots__: ('attr2', 'attr4')
Traceback (most recent call last):
File "boom.py", line 30, in test
class TestClass(c1, c2):
TypeError: multiple bases have instance lay-out conflict
DEBUG:root:******************** new class test ********************
ERROR:root:BOOM!!!
c1: <class '__main__.C12'>
c2: <class '__main__.C3byC12'>
__slots__: ('attr2',)
Traceback (most recent call last):
File "boom.py", line 30, in test
class TestClass(c1, c2):
TypeError: Cannot create a consistent method resolution
order (MRO) for bases C3byC12, C12
DEBUG:root:******************** new class test ********************
DEBUG:root:No Boom!
c1: <class '__main__.C3byC12'>
c2: <class '__main__.C12'>
__slots__: ('attr4',)
DEBUG:root:Instance __slots__:('attr4',)
DEBUG:root:Attributes in instance dir: X X X X
DEBUG:root:******************** new class test ********************
ERROR:root:BOOM!!!
c1: <class '__main__.C1234'>
c2: <class '__main__.C34'>
__slots__: ('attr2', 'attr4')
Traceback (most recent call last):
File "boom.py", line 30, in test
class TestClass(c1, c2):
TypeError: multiple bases have instance lay-out conflict
DEBUG:root:******************** new class test ********************
DEBUG:root:No Boom!
c1: <class '__main__.C1234'>
c2: <class '__main__.CEmpty'>
__slots__: ('attr2', 'attr4')
DEBUG:root:Instance __slots__:('attr2', 'attr4')
DEBUG:root:Attributes in instance dir: X X X X
DEBUG:root:******************** new class test ********************
DEBUG:root:No Boom!
c1: <class '__main__.C12'>
c2: <class '__main__.CEmpty'>
__slots__: ('attr2', 'attr4')
DEBUG:root:Instance __slots__:('attr2', 'attr4')
DEBUG:root:Attributes in instance dir: X X _ X
DEBUG:root:******************** new class test ********************
DEBUG:root:No Boom!
c1: <class '__main__.C12'>
c2: <class '__main__.CEmpty'>
__slots__: ('attr1', 'attr2')
DEBUG:root:Instance __slots__:('attr1', 'attr2')
DEBUG:root:Attributes in instance dir: X X _ _
DEBUG:root:******************** new class test ********************
DEBUG:root:No Boom!
c1: <class '__main__.C12'>
c2: <class '__main__.CEmpty'>
__slots__: ()
DEBUG:root:Instance __slots__:()
DEBUG:root:Attributes in instance dir: X X _ _
DEBUG:root:******************** new class test ********************
DEBUG:root:No Boom!
c1: <class '__main__.CEmpty'>
c2: <class '__main__.C1234'>
__slots__: ('attr2', 'attr4')
DEBUG:root:Instance __slots__:('attr2', 'attr4')
DEBUG:root:Attributes in instance dir: X X X X
DEBUG:root:******************** new class test ********************
DEBUG:root:No Boom!
c1: <class '__main__.CEmpty'>
c2: <class '__main__.C12'>
__slots__: ('attr3',)
DEBUG:root:Instance __slots__:('attr3',)
DEBUG:root:Attributes in instance dir: X X X _
DEBUG:root:******************** new class test ********************
ERROR:root:BOOM!!!
c1: <class '__main__.C12'>
c2: <class '__main__.C34'>
__slots__: not defined
Traceback (most recent call last):
File "boom.py", line 28, in test
class TestClass(c1, c2): pass
TypeError: multiple bases have instance lay-out conflict
DEBUG:root:******************** new class test ********************
DEBUG:root:No Boom!
c1: <class '__main__.C12'>
c2: <class '__main__.CEmpty'>
__slots__: not defined
WARNING:root:Instance has __dict__!
DEBUG:root:Attributes in instance dir: X X _ _
如您所见,您有两种选择:
__slots__ = ()
为除一个父类之外的所有类定义,
- 或使其中一个父母成为另一个父母的子类。
请注意,您也应该__slots__
在新类中定义,否则它会得到一个__dict__
.