Как динамически добавлять миксины в качестве базовых классов, не получая ошибок MRO?
Скажи у меня классA
, B
а такжеC
.
Учебный классA
а такжеB
оба смешанные классы для классаC
.
<code>class A( object ): pass class B( object ): pass class C( object, A, B ): pass </code>
Это не будет работать при создании экземпляра класса C. Я должен был бы удалитьobject
из класса С, чтобы заставить его работать. (В противном случае у вас возникнут проблемы с MRO).
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution
order (MRO) for bases B, object, A
Однако мой случай немного сложнее. В моем случае классC
этоserver гдеA
а такжеB
будут плагины, которые загружаются при запуске. Они находятся в своей собственной папке.
У меня также есть класс с именемCfactory
, В Cfactory у меня есть__new__
метод, который создаст полностью функциональный объект C. В__new__
метод яsearch для плагинов, загрузите их, используя__import__
, а затем назначить ихC.__bases__ += (loadedClassTypeGoesHere, )
Таким образом, возможно следующее: (сделано довольно абстрактно)
<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>
Это снова не будет работать, и снова выдаст ошибки MRO:
TypeError: Cannot create a consistent method resolution
order (MRO) for bases object, A
Легким решением проблемы является удалениеobject
базовый класс отA
а такжеB
, Однако это сделает их объектами старого стиля, которых следует избегать, когда эти плагины запускаются в автономном режиме (что должно быть возможно, для UnitTest)
Еще одно простое решение - удалениеobject
отC
но это также сделает его классом старого стиля иC.__bases__
будет недоступен, поэтому я не могу добавить дополнительные объекты в базуC
Что было бы хорошим архитектурным решением для этого и как бы вы сделали что-то подобное? Пока я могу жить с классами старого стиля для самих плагинов. Но я их не использую.