Re: [Python-es]Re:[Python-es]Re: [Python-es]Evolución dinámica de los objetos a diferentes clases

Ernesto Revilla aerd en retemail.es
Vie Ago 23 20:28:34 CEST 2002


Extraordinariamente interesante,

todavía tengo que ir a través del código un poco más detenidamente.

Gracias.
Erny

----- Original Message -----
From: "Chema Cortes" <chemacortes en wanadoo.es>
To: <python-es en aditel.org>
Sent: Friday, August 23, 2002 12:48 PM
Subject: [Python-es]Re:[Python-es]Re: [Python-es]Evolución dinámica de los
objetos a diferentes clases


> > 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
>
> _______________________________________________
> Python-es mailing list
> Python-es en aditel.org
> http://listas.aditel.org/listinfo.py/python-es






Más información sobre la lista de distribución Python-es