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