Скажем, у меня есть класс A
, B
и C
.
Классы A
и B
являются классами примесей для класса C
.
class A( object ):
pass
class B( object ):
pass
class C( object, A, B ):
pass
Это не будет работать при создании экземпляра класса C. Мне пришлось бы удалить object
из класса C, чтобы заставить его работать. (Иначе у вас будут проблемы с MRO).
TypeError:Ошибка при вызове баз метаклассов
Невозможно создать согласованное разрешение метода
заказ (ТОиР)для баз Б, объекта, А
Однако мой случай немного сложнее. В моем случае класс C
— это сервер , где A
и B
будут плагинами, загружаемыми при запуске. Они находятся в своей собственной папке.
У меня также есть класс с именем Cfactory
. В Cfactory у меня есть метод __new__
, который создаст полнофункциональный объект C. В методе __new__
я ищу плагины, загружаю их с помощью __import__
и затем назначаю ихC.__bases__ += (loadedClassTypeGoesHere, )
Таким образом, следующая возможность:(сделала его довольно абстрактным)
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()
Это снова не будет работать и снова приведет к ошибкам MRO:
TypeError :Невозможно создать согласованное разрешение метода
закажите (MRO)для базового объекта, A
Легко исправить это, удалив базовый класс object
из A
и B
. Однако это сделает их объектами старого-стиля, которых следует избегать, когда эти плагины запускаются автономно-отдельно (, что должно быть возможно с помощью UnitTest)
Другое простое решение — удаление object
из C
но это также сделает его классом в старом стиле -и C.__bases__
будет недоступен, поэтому я не могу добавить дополнительные объекты в базуC
Какое было бы хорошее архитектурное решение для этого и как бы вы это сделали? что-то вроде этого?На данный момент я могу жить со старыми-классами для самих плагинов. Но я предпочитаю не использовать их.