Esto define dinámicamente una nueva clase GentlePerson
, y reasigna p
'clase s a ella:
class Gentleman(object):
def introduce_self(self):
return "Hello, my name is %s" % self.name
class Person(object):
def __init__(self, name):
self.name = name
p = Person("John")
p.__class__ = type('GentlePerson',(Person,Gentleman),{})
print(p.introduce_self())
# "Hello, my name is John"
según su petición, esto modifica p
' s bases, pero no altera p
clase original Person
. Por lo tanto, otras instancias de Person
no se ven afectadas (y generarían un AttributeError
si se llamaran introduce_self
).
A pesar de que no se le pidió directamente en la pregunta, voy a añadir para que los Googlers y curiosos, que también es posible cambiar dinámicamente las bases de una clase, sino (que yo sepa) sólo si la clase no hereda directamente de object
:
class Gentleman(object):
def introduce_self(self):
return "Hello, my name is %s" % self.name
class Base(object):pass
class Person(Base):
def __init__(self, name):
self.name = name
p = Person("John")
Person.__bases__=(Gentleman,object,)
print(p.introduce_self())
# "Hello, my name is John"
q = Person("Pete")
print(q.introduce_self())
# Hello, my name is Pete
¿Por qué downvote esto sin un comentario? Tal vez porque la palabra Ruby aparece en el texto? oO –
Uuuuurrgghhh !!!!! Cambiar una instancia sin cambiar la clase es una receta para el desastre. La mejor manera de hacerlo es crear una subclase de 'Persona' y mezclar' Caballero' en eso. – katrielalex
@katrielalex: Probablemente tengas razón en la mayoría de los casos. Sin embargo, necesito esa funcionalidad porque quiero agregar funcionalidad a una biblioteca de terceros cuya interfaz no puedo cambiar. Tuve que elegir entre mixins o el patrón proxy, del cual este último no me gusta mucho. –