This article tiene un fragmento que muestra el uso de __bases__
para cambiar dinámicamente la jerarquía de herencia de algún código de Python, agregando una clase a una colección de clases existente de las clases de las que hereda. Ok, eso es difícil de leer, el código es probablemente más claro:¿Cómo cambiar dinámicamente la clase base de instancias en tiempo de ejecución?
class Friendly:
def hello(self):
print 'Hello'
class Person: pass
p = Person()
Person.__bases__ = (Friendly,)
p.hello() # prints "Hello"
Es decir, Person
no hereda de Friendly
en el nivel de la fuente, sino que se añade esta relación de herencia dinámicamente en tiempo de ejecución mediante la modificación del atributo __bases__
de la clase Persona. Sin embargo, si cambia Friendly
y Person
a ser nuevas clases de estilo (heredando de objeto), se obtiene el siguiente error:
TypeError: __bases__ assignment: 'Friendly' deallocator differs from 'object'
Un poco de google sobre esto parece indicate some incompatibilities entre el nuevo estilo y las clases de estilo antiguo en lo que respecta a cambiar la jerarquía de herencia en tiempo de ejecución. Específicamente: "New-style class objects don't support assignment to their bases attribute".
Mi pregunta, ¿es posible hacer que el ejemplo amistoso/persona anterior utilice clases de estilo nuevo en Python 2.7+, posiblemente mediante el uso del atributo __mro__
?
Descargo de responsabilidad: me doy cuenta de que este código es oscuro. Me doy cuenta de que en trucos de código de producción real como este tienden a ser ilegibles, esto es puramente un experimento mental, y para que los usuarios aprendan algo sobre cómo Python se ocupa de los problemas relacionados con la herencia múltiple.
También es bueno para los estudiantes leer esto si no están familiarizados con metaclass, tipo(), ...: http://www.slideshare.net/gwiener/metaclasses-in-python :) – loolooyyyy
Aquí está mi uso caso. Estoy importando una biblioteca que tiene clase B que hereda de la clase A. – FutureNerd
Aquí está mi caso de uso real. Estoy importando una biblioteca que tiene clase B heredando de la clase A. Quiero crear New_A heredando desde A, con new_A_method(). Ahora quiero crear New_B heredando de ... bueno, de B como si B heredara de New_A, de modo que los métodos de B, los métodos de A, y new_A_method() estén todos disponibles para las instancias de New_B. ¿Cómo puedo hacer esto sin parche de monos en la clase A existente? – FutureNerd