Jak dynamicznie dodawać miksy jako klasy bazowe bez otrzymywania błędów MRO?
Powiedz, że mam klasęA
, B
iC
.
KlasaA
iB
obie klasy mixin dla klasyC
.
<code>class A( object ): pass class B( object ): pass class C( object, A, B ): pass </code>
To nie zadziała podczas tworzenia instancji klasy C. Musiałbym usunąćobject
z klasy C, aby to działało. (Inaczej będziesz miał problemy z MRO).
TypeError: Błąd podczas wywoływania baz metaklasy
Nie można utworzyć spójnej rozdzielczości metody
zamówienie (MRO) dla baz B, obiekt, A
Jednak moja sprawa jest nieco bardziej skomplikowana. W mojej klasie przypadkuC
jestserwer gdzieA
iB
będą wtyczki ładowane podczas uruchamiania. Znajdują się one we własnym folderze.
Mam też klasę o nazwieCfactory
. W Cfactory mam__new__
metoda, która stworzy w pełni funkcjonalny obiekt C. W__new__
metoda ISzukaj dla wtyczek, ładuj je za pomocą__import__
, a następnie przypisz je doC.__bases__ += (loadedClassTypeGoesHere, )
Tak więc poniższe jest możliwe: (zrobiło to dość abstrakcyjne)
<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>
To znowu nie zadziała i ponownie spowoduje błędy MRO:
Błąd typu: nie można utworzyć spójnej rozdzielczości metody
zamówienie (MRO) dla obiektu bazowego, A
Łatwym rozwiązaniem tego problemu jest usunięcieobject
baseclass fromA
iB
. Jednak spowoduje to, że będą to obiekty w starym stylu, których należy unikać, gdy te wtyczki są uruchamiane autonomicznie (co powinno być możliwe, UnitTest wise)
Innym łatwym rozwiązaniem jest usunięcieobject
zC
ale to również uczyni z niego klasę w starym stylu iC.__bases__
będzie niedostępny, więc nie mogę dodawać dodatkowych obiektów do bazyC
Jakie byłoby dobre rozwiązanie architektoniczne i jak byś zrobił coś takiego? Na razie mogę żyć ze starymi klasami dla samych wtyczek. Ale raczej ich nie używam.