Digamos que tengo una clase A
, B
y C
.¿Cómo agrego dinámicamente mixins como clases base sin obtener errores de MRO?
La clase A
y B
son ambas clases mixin para la clase C
.
class A(object):
pass
class B(object):
pass
class C(object, A, B):
pass
esto no funcionará cuando una instancia de la clase C. tendría que quitar object
de la clase C para hacer que funcione. (De lo contrario, obtendrá problemas de MRO).
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution
order (MRO) for bases B, object, A
Sin embargo, mi caso es un poco más complicado. En mi caso, la clase C
es un servidor donde A
y B
serán complementos que se cargan al inicio. Estos residen en su propia carpeta.
También tengo una clase llamada Cfactory
. En Cfactory tengo un método __new__
que creará un objeto C. completamente funcional en el método __new__
Yo busco para los plugins, los carga usando __import__
, y luego asignarlos a C.__bases__ += (loadedClassTypeGoesHere,)
Así que la siguiente es una posibilidad: (hacía bastante abstracto)
class A(object):
def __init__(self): pass
def printA(self): print "A"
class B(object):
def __init__(self): pass
def printB(self): print "B"
class C(object):
def __init__(self): pass
class Cfactory(object):
def __new__(cls):
C.__bases__ += (A,)
C.__bases__ += (B,)
return C()
De nuevo, esto no va a funcionar, y dará a los errores de MRO nuevo:
TypeError: Cannot create a consistent method resolution
order (MRO) for bases object, A
Un Una solución fácil para esto es eliminar la clase base object
de A
y B
. Sin embargo esto hará que los objetos de estilo antiguo que deben ser evitados cuando estos plugins se ejecutan autónomo (que debería ser posible, unittest sabia)
Otra solución fácil es la eliminación de object
de C
pero esto también hará que sea una clase de estilo antiguo y C.__bases__
no estarán disponibles por lo que no puedo agregar objetos adicionales a la base de C
¿Cuál sería una buena solución arquitectónica para esto y cómo harías algo como esto? Por ahora puedo vivir con clases antiguas para los plugins. Pero prefiero no usarlos.
Las clases de estilo antiguo no existen en Python 3, por lo que necesitará una solución eventualmente. –
Realmente cierto. –