Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Utilisation de la classe Property

2 réponses
Avatar
Fouff
Bien le bonjour à toutes et tous.
Pour bien commencer, je suis sous win2000 et avec l'ami python 2.4.1

Soit une classe C dans un fichier toto.py

import qui vont bien pour le fichier
class C:
def __init__(self):
self.variable = "toto"

def getMethod(self):
return self.variable

def setMethod(self, value):
self.variable = value

def initMethod(self):
self.variable = "titi"

prop = property(fget=getMethod, fset=setMethod, fdel=initMethod, doc=""".""")

Maintenant :
>>> import toto
>>> c = toto.C()
>>> print c.prop
toto
>>> c.prop = "TITI"
>>> print c.prop
TITI
>>> print c.getMethod()
toto

Et là, c'est le drame !!!!!

Je me trouve fort désapointé devant cette réponse pour le moins inatendue, je m'attendais, je
l'avoue, à ce que ce soit "TITI" !

Si quelqu'un avait l'extrème amabilité de m'expliquer ce que je fais de pas bien dans cet exemple
pour que celui-ci refuse obstinément de me répondre "TITI" (et pour les malins, je ne suis pas
grosminet !).

D'avance merci.
Fouff

2 réponses

Avatar
Bruno Desthuilliers
Bien le bonjour à toutes et tous.
Pour bien commencer, je suis sous win2000


<troll>
Pour bien commencer : sincères condoléances !-)
</troll>

et avec l'ami python 2.4.1

Soit une classe C dans un fichier toto.py

import qui vont bien pour le fichier
class C:


je t'arrête tout de suite : le protocole descripteur (et donc property,
qui est basée sur ce protocole) ne fonctionne pas correctement avec les
classes "classic" (modèle objet antédiluvien, mais toujours supporté
pour raisons de compatibilité). Il faut utiliser les classes 'new style'
(modèle objet nettement amélioré, introduit dans Python 2.2.x). Donc:

class C(object):

def __init__(self):
self.variable = "toto"

def getMethod(self):
return self.variable

def setMethod(self, value):
self.variable = value

def initMethod(self):
self.variable = "titi"

prop = property(fget=getMethod, fset=setMethod, fdel=initMethod,


fdel est supposé gérer la suppression de l'attribut, pas son initialisation.

Accessoirement, un idiome pour éviter de pourrir l'espace de nommage de
ta classe:

class C(object):
def __init__(self):
self.prop = 42

@apply
def prop():
def fget(self):
return self._prop
def fset(self, val):
self._prop = val
def fdel(self):
del set._prop
doc = """
une prop qui ne sert à rien
"""
return property(**locals)




Maintenant :
import toto
c = toto.C()
print c.prop
toto



c.prop = "TITI"
print c.prop
TITI



print c.getMethod()
toto




Et là, c'est le drame !!!!!

Je me trouve fort désapointé devant cette réponse pour le moins
inatendue, je m'attendais, je l'avoue, à ce que ce soit "TITI" !

Si quelqu'un avait l'extrème amabilité de m'expliquer ce que je fais de
pas bien dans cet exemple pour que celui-ci refuse obstinément de me
répondre "TITI" (et pour les malins, je ne suis pas grosminet !).


Réponse plus haut.

Pour plus de détail: avec les classes 'classic', le protocol descripteur
ne fonctionne qu'en lecture. Donc quand ta ligne c.prop = 'TITI' ne
passe pas par la case setMethod, et crée directement une variable
d'instance 'prop' avec la valeur 'TITI' - qui bien sûr masque l'attribut
de class de même nom. Tu peux constater ça par toi-même en affichant le
__dict__ de ton instance avant et après cette ligne.

HTH




Avatar
Fouff
Alors, là, un très grand MERCI.
Du grand art, avec l'explication technique en plus, rien à redire.

Fouff

Bien le bonjour à toutes et tous.
Pour bien commencer, je suis sous win2000


<troll>
Pour bien commencer : sincères condoléances !-)
</troll>

et avec l'ami python 2.4.1

Soit une classe C dans un fichier toto.py

import qui vont bien pour le fichier
class C:


je t'arrête tout de suite : le protocole descripteur (et donc property,
qui est basée sur ce protocole) ne fonctionne pas correctement avec les
classes "classic" (modèle objet antédiluvien, mais toujours supporté
pour raisons de compatibilité). Il faut utiliser les classes 'new style'
(modèle objet nettement amélioré, introduit dans Python 2.2.x). Donc:

class C(object):

def __init__(self):
self.variable = "toto"

def getMethod(self):
return self.variable

def setMethod(self, value):
self.variable = value

def initMethod(self):
self.variable = "titi"

prop = property(fget=getMethod, fset=setMethod, fdel=initMethod,


fdel est supposé gérer la suppression de l'attribut, pas son
initialisation.

Accessoirement, un idiome pour éviter de pourrir l'espace de nommage de
ta classe:

class C(object):
def __init__(self):
self.prop = 42

@apply
def prop():
def fget(self):
return self._prop
def fset(self, val):
self._prop = val
def fdel(self):
del set._prop
doc = """
une prop qui ne sert à rien
"""
return property(**locals)




Maintenant :
import toto
c = toto.C()
print c.prop
toto



c.prop = "TITI"
print c.prop
TITI



print c.getMethod()
toto




Et là, c'est le drame !!!!!

Je me trouve fort désapointé devant cette réponse pour le moins
inatendue, je m'attendais, je l'avoue, à ce que ce soit "TITI" !

Si quelqu'un avait l'extrème amabilité de m'expliquer ce que je fais
de pas bien dans cet exemple pour que celui-ci refuse obstinément de
me répondre "TITI" (et pour les malins, je ne suis pas grosminet !).


Réponse plus haut.

Pour plus de détail: avec les classes 'classic', le protocol descripteur
ne fonctionne qu'en lecture. Donc quand ta ligne c.prop = 'TITI' ne
passe pas par la case setMethod, et crée directement une variable
d'instance 'prop' avec la valeur 'TITI' - qui bien sûr masque l'attribut
de class de même nom. Tu peux constater ça par toi-même en affichant le
__dict__ de ton instance avant et après cette ligne.

HTH