Me he enfrentado a este error y realmente quería usar ranuras para mis nodos de base de datos personalizados. Aquí está el conjunto de pruebas que he hecho (Su en 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)
Éstos son los resultados:
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 _ _
Como se puede ver, tiene dos opciones:
- Defina
__slots__ =()
para todas menos una de las clases padre,
- o haga que uno de los padres pertenezca a la subclase del otro.
en cuenta que debe definir __slots__
en la nueva clase también, de lo contrario se pone un __dict__
.
Confieso que no estoy 100% entendiendo esto tampoco, pero basado en las fuentes que vinculó, no parece que sea un error.Como dije antes, no estoy al 100% en esto, pero la mejor "solución alternativa" parece ser limitar el uso de '__slots__'. ¿Hay alguna razón específica por la que tengas que usarlos? –
Están siendo generados automáticamente por una metaclase para almacenar un atributo de instancia mágica fuera de su diccionario. El sistema ejecuta automáticamente una conversión en todas las clases base, lo que conduce al problema de herencia múltiple. –