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

Chema Cortés chemacortes en wanadoo.es
Sab Ago 24 18:53:10 CEST 2002


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

El Sáb 24 Ago 2002 11:41, Marcos Sánchez Provencio escribió:

> Yo creo que debería haber (no sé si hay PEPs de esto) un método especial
> __cast__ que haría los cambios necesarios.


Lo más parecido es el __coerce__. Pero sospecho que para ver algún día un 
operador __cast__ habría que conseguir la unificación real de tipos y clases.

> unaPersona=Persona()
> nuevoCliente=Cliente.__cast__(unaPersona, id_cliente=2323)


En el python actual, el casting lo hace el contructor __init__ utilizando el 
"polimorfismo" característico de programación orientada a objeto. Es como se 
simulan las funciones para conversión de tipos. Por ejemplo:

a=1.0   # float
a=str(a) # string desde float
a=complex(a) # complex desde string


> Ahora veo que no puede ser un método, sino una función estática de la
> clase.
> Código para Python 2.2 sin verificar:
>
> class Cliente:
>   def __cast__(objetoBase, **kw):
>     if type(objetoBase)==TipoPersona:
>       objetoBase.__class__=Cliente
>       objetoBase.id_cliente=kw['id_cliente']
>     else:
>       raise NotImplemented
>   __cast__=classmethod(__cast__)

Ya veo que dices que no lo has revisado, porque hay algunos fallos 
importantes. Para que __cast__ fuera método estático, debería ser:

    __cast__=staticmethod(__cast__)

A parte de esto, type(objetoBase)==TipoPersona no funcionará como esperas tal 
como están definidas las clases. Deberían utilizar el nuevo mecanismo de 
generación de clases (que derivan todas de la clase primaria 'object'). 
También se podría haber utilizado la función 'isinstance()':

   if isinstance(objetoBase,Persona):


Pero tal como decía antes, si usamos el constructor polimórfico __init__ para 
hacer operaciones de casting, quedaría así:


class Cliente(Persona):
  def __init__(self,*args):
    """Interfaces:

    Cliente(nombre, id_cliente) -> Nuevo cliente
    Cliente(persona, id_cliente) -> Cliente a partir de persona
    """

    if len(args)!=0:
      raise TypeError, "Necesitaba exactamente 2 argumentos"

    if type(args[0]) is types.InstanceType:
       # Nos pasan un objeto
       obj=args[0]
       if isinstance(obj, Persona):
          # Casting a partir de un objeto de la clase "Persona"
          self.nombre=obj.nombre
          self.id_cliente=int(args[1])
       else:
          # Podíamos mirar otros "castings"
          # y si no, dar una excepción
    else:
       self.nombre=str(args[0])
       self.id_cliente=int(args[0])


> De momento habría que llamarlo a pelo, pero quedaría más mono con
>
> Cliente[unaPersona, id_cliente=2323]

Con la última definición sería así:

Cliente(unaPersona, id_cliente=2323)


> Parecido a crear una nueva instancia,, pero diferente, o soluciones
> similares. ¿Un voluntario para sacar un parche para la 2.3? ¿Se puede
> redefinir __lsub__ para que haga eso?

No entiendo a qué te refieres con __lsub__


Saludos,
- -- 
Chema Cortes (chemacortes en wanadoo.es) | LinuxUser#142755 - SuSE Linux 8.0
  ZARALINUX  http://www.zaralinux.org | "La ignorancia se apodera de quien
    PYTANDO  http://pytando.sf.net    |     se contenta con lo que sabe"
      PGPKEY: mailto:chemacortes en wanadoo.es?subject=__PGPKEY__

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE9Z7n5HLTQrABk8H0RAo1KAJ4jGSKBwpb52N183ErAIy6QBFIszgCg7aak
TjzzkFxJgAKzmF2H6seG5AE=
=Y9hC
-----END PGP SIGNATURE-----


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