Como adicionar dinamicamente mixins como classes base sem obter erros de MRO?
Diga que eu tenho uma aulaA
, B
eC
.
ClasseA
eB
são ambas as classes mixin para a classeC
.
<code>class A( object ): pass class B( object ): pass class C( object, A, B ): pass </code>
Isso não funcionará ao instanciar a classe C. Eu teria que removerobject
da classe C para fazê-lo funcionar. (Senão você terá problemas de MRO).
TypeError: Erro ao chamar as bases de metaclasse
Não é possível criar uma resolução de método consistente
ordem (MRO) para bases B, objeto, A
No entanto, meu caso é um pouco mais complicado. Na minha aula de casoC
é umservidor OndeA
eB
serão plugins que são carregados na inicialização. Estes estão residindo em sua própria pasta.
Eu também tenho uma classe chamadaCfactory
. No Cfactory eu tenho um__new__
método que criará um objeto totalmente funcional C. No__new__
método Iprocurar para plugins, carregue-os usando__import__
e, em seguida, atribua-os aC.__bases__ += (loadedClassTypeGoesHere, )
Então, o seguinte é uma possibilidade: (tornou bastante abstrato)
<code>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() </code>
Isso novamente não funcionará e dará novamente os erros de MRO:
TypeError: Não é possível criar uma resolução de método consistente
ordem (MRO) para o objeto base, A
Uma solução fácil para isso é remover oobject
baseclass deA
eB
. No entanto, isso fará com que sejam objetos antigos que devem ser evitados quando esses plug-ins estiverem sendo executados autônomos (o que deve ser possível, UnitTest sábio)
Outra solução fácil é removerobject
deC
mas isso também fará com que seja uma aula de estilo antigo eC.__bases__
ficará indisponível, portanto, não posso adicionar objetos extras à base deC
Qual seria uma boa solução arquitetônica para isso e como você faria algo assim? Por enquanto eu posso viver com classes antigas para os próprios plugins. Mas eu prefiro não usá-los.