Properties y metodos 'virtuales'

Chema Cortés chemacortes en wanadoo.es
Dom Sep 1 12:03:00 CEST 2002


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

El Sáb 31 Ago 2002 17:57, Ernesto Revilla escribió:
> Por defecto, todos los métodos definidos en la clase son 'virtuales',
> pienso que también debería existir una manera para hacer que los métodos
> llamados a partir de un 'property' lo sean.

Todas las extensiones que se están introduciendo se hacen sin alterar la 
sintaxis. Se confía en ir introduciendo poco a poco estas características a 
medida que los programadores las vayan aceptando.

De momento, el mecanismo funciona como una búsqueda simple de atributos en los
diccionarios de cada clase, y es como debes ver la "virtualidad" de atributos. 
Fíjate bien que tu problema sería similar, a éste:

class X(object):
    def get_a(self):
        print "Primer X.get_a"
        return self._a
    def set_a(self,value):
        self._a=value
    a=property(get_a,set_a)
    def get_a(self):
        print "Segundo X.get_a"
        return self._a

x=X()
x.a=10
print x.a

Puedes observar que la propiedad 'a' emplea el primer método 'X.get_a', no el 
segundo que lo había sustituído. Esto te viene a decirte que, una vez creada 
la propiedad, ésta es independiente de las funciones que lo han creado. Es la 
propiedad 'a' la que es 'virtual', y la que deberías suplantar en las clases 
derivadas.


> Todavía no le veo el camino, así que no puedo ver si llega lejos o no. Lo
> único que se me ocurre es alguna cosa como esta:
>
> class virtualproperty(property):
>     def __init__(self, getmethod=None, setmethod=None, delmethod=None,
> doc=''):
>         if getmethod: getmethod=eval("lamda self: self.%s()" %
> getmethod.func_name)
>         if setmethod: setmethod=eval("lamda self: self.%s()" %
> setmethod.func_name)
>         if delmethod: delmethod=eval("lamda self: self.%s()" %
> delmethod.func_name)
>         property.__init__(self, getmethod, setmethod, delmethod, doc)
>
> Pero quizá tengas trazón que sea mejor con tratar la creación de los
> properties desde las metaclases.


Por este camino muy poco podrías conseguir.Como mejor veo una solución, en el 
estado actual de las cosas, es utilizando metaclases:

class X(object):
    class __metaclass__(type):
        def __init__(cls, name, bases, dict):
            cls.a=property(cls.get_a,cls.set_a)
    def set_a(self,value):
        self._a=value
    def get_a(self):
        print "leyendo desde X"
        return self._a
#    a=property(get_x,set_x)
# No hace falta. Ya se hace desde __metaclass__.__init__

class Y(X):
    def get_a(self):
        print "leyendo desde Y"
        return X.get_a(self)

Cada vez que creemos una clase derivada de X se llamará al método constructor
__metaclass__.__init__ donde crearemos la propiedad 'a' para la clase.



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

iD8DBQE9ceXZHLTQrABk8H0RAiEUAJ9+BLfO6H5Q0aoGNF0MeRtD0X9ppwCeIh6V
F7+FBCUNDBDjCQ/sX8LB+lI=
=qhJZ
-----END PGP SIGNATURE-----





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