Re:[Python-es]Re: [Python-es]Evolución dinámica de los objetos a diferentes clases
Chema Cortes
chemacortes en wanadoo.es
Vie Ago 23 12:48:49 CEST 2002
> Eso está claro, pero ¿qué pasa si una persona se convierte en cliente?
> ¿Tengo que borrarlo de personas y crear una nueva instancia de cliente? ¿Qué
> pasa si una persona es a la vez cliente y proveedor?
Lo que estás pidiendo es una transformación de "casting". Python sí puede hacerlo, más o menos decentemente. Aquí te pongo código que te puede orientar:
# Las clases con las que trabajamos
class Persona:
def __init__(self,nombre):
self.nombre=nombre
class Cliente:
def __init__(self, nombre, cod_cliente):
self.nombre=nombre
self.cod_cliente=cod_cliente
class Proveedor:
def __init__(self, nombre, cod_proveedor):
self.nombre=nombre
self.cod_proveedor=cod_proveedor
# No he puesto que "Cliente" y "Proveedor" hereden
# de "Persona" para hacerlo más general (Cliente
# y Proveedor también podrían ser una empresa)
# Creo una persona
p=Persona("Pepe")
# Se convierte en "Cliente" (y deja de ser "Persona")
# Un método sencillo
q=Cliente(p.nombre, 1000) # Creamos un nuevo cliente
q.__dict__.update(p.__dict__) # Actualizamos a partir de 'p'
p=q
# Un método algo más seguro
import new
p=new.instance(Cliente,p.__dict__)
# Como con new.instance no se ejecuta el constructor
# hay que hacer algunos apañanos a mano
p.cod_cliente = 1000
# Ahora queremos convertirlo en "Proveedor", pero que siga
# como "Cliente"
# Creamos una nueva clase
c=new.classobj("ClienteProveedor", (Cliente, Proveedor) , {} )
p=new.instance(c,p.__dict__)
p.cod_proveedor=5
# Ahora que está un poco claro cómo hacerlo, generamos una "metaclase"
class Negocio:
classes={} # almacén para las clases de Negocio
def create(name, *classes): # Método estático
k=Negocio.classes.get(name,None)
if not k:
k=new.classobj(name, (Negocio,)+classes, {})
Negocio.classes[name]=k
return k
create=staticmethod(create)
def cast(self, klass, **args):
if klass.__name__ not in Negocio.classes.keys():
raise TypeError, klass
self.__class__=klass
self.__dict__.update(args)
# Y así se usaría
kPersona=Negocio.create("Persona",Persona)
p=kPersona("Pepe")
kCliente=Negocio.create("Cliente",Cliente)
p.cast(kCliente, cod_cliente=1000)
kClienteProveedor=Negocio.create("ClienteProveedor",Cliente,Proveedor)
p.cast(kClienteProveedor, cod_proveedor=5)
#-----------------
Seguramente se puede hacer mejor. Si aprovechas la idea, me gustaría ver cómo queda el resultado final.
Saludos,
--
Chema Cortes (chemacortes en wanadoo.es)
_____________________________________________________________________
Horas ilimitadas para leer y enviar correos con Tarifa Plana Wanadoo
¡¡ desde las 3 de la tarde!!
Compruébalo en http://www.wanadoo.es/acceso-internet
Más información sobre la lista de distribución Python-es