This article ha uno snippet che mostra l'utilizzo di __bases__
per modificare dinamicamente la gerarchia di ereditarietà di alcuni codici Python, aggiungendo una classe a un insieme di classi esistenti di classi da cui eredita. Ok, questo è difficile da leggere, il codice è probabilmente più chiara:Come modificare dinamicamente la classe base delle istanze in fase di runtime?
class Friendly:
def hello(self):
print 'Hello'
class Person: pass
p = Person()
Person.__bases__ = (Friendly,)
p.hello() # prints "Hello"
Cioè, Person
non eredita dal Friendly
a livello sorgente, ma questo rapporto eredità si aggiunge dinamicamente a runtime modifica dell'attributo __bases__
della classe Person. Tuttavia, se si cambia Friendly
e Person
di essere nuove classi di stile (ereditando da oggetto), si ottiene il seguente errore:
TypeError: __bases__ assignment: 'Friendly' deallocator differs from 'object'
Un po 'di Googling su questo sembra indicate some incompatibilities tra new-style e classi di stile vecchi per quanto riguarda la modifica della gerarchia di ereditarietà in fase di runtime. Nello specifico: "New-style class objects don't support assignment to their bases attribute".
La mia domanda, è possibile fare l'esempio Friendly/Person sopra usando le classi di nuovo stile in Python 2.7+, possibilmente usando l'attributo __mro__
?
Disclaimer: Mi rendo perfettamente conto che si tratta di un codice oscuro. Mi rendo perfettamente conto che nei trucchi del codice di produzione reale come questo tendono a delimitare illeggibili, questo è puramente un esperimento mentale, e per i funzies imparare qualcosa su come Python si occupa di problemi legati all'ereditarietà multipla.
È anche piacevole per gli studenti leggere questo se non hanno familiarità con metaclass, type(), ...: http://www.slideshare.net/gwiener/metaclasses-in-python :) – loolooyyyy
Ecco il mio uso Astuccio. Sto importando una libreria che ha una classe B che eredita dalla classe A. – FutureNerd
Ecco il mio caso di utilizzo effettivo. Sto importando una libreria che ha la classe B che eredita dalla classe A. Voglio creare New_A ereditando da A, con new_A_method(). Ora voglio creare New_B ereditando da ... beh, da B come se B erediti da New_A, in modo che i metodi di B, i metodi di A e new_A_method() siano tutti disponibili per le istanze di New_B. Come posso fare questo senza applicare patch per scimmie alla classe A esistente? – FutureNerd