Bonjour,
L'autre jour, je suis tombé sur ça dans la doc de Python:
class C(object):
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
class D(C):
@C.x.getter
def x(self):
return self._x * 2
@x.setter
def x(self, value):
self._x = value / 2
Je ne comprend pas bien le sens du @C.x.getter
. Pourquoi y a t'il une référence à la classe C ? Quelqu'un pourrait m'expliquer ?
Merci.
# Supposition
Posté par benoar . Évalué à 2.
Je suppose que c'est pour ne pas « écraser » la propriété de la classe parente. Si tu mettais simplement @property def x(… dans la classe D, tous les « accesseurs » (getter, setter et deleter) de la classe parente disparaîtraient, car ils sont tous associés à la valiable (de classe) x. En particulier, ici, on perdrait le deleter, puisqu'on redéfinit tout de même le getter et le setter.
Quand tu précises @une_propriété.getter ou autre setter/deleter, la variable contenant la propriété va être écrasée, mais en gardant les accesseurs déjà déclarées, car c'est le décorateur spécifique à la propriété déjà définie auparavant qui est utilisé. Ici, dans la classe D, on utilise le décorateur de la classe C « C.x.getter » pour créer un getter qui conservera les autres accesseurs. Une fois cette propriété définie dans la classe D, on peut l'utiliser pour les accesseurs suivants (ici, le setter de D).
PS : j'utilise le mot « accesseur » pour désigner aussi bien le getter que le setter et deleter ; je ne trouve pas de meilleur mot.
[^] # Re: Supposition
Posté par sifu . Évalué à 1.
Merci.
Du coup, je ne comprend pas pourquoi le
@x.setter
dans D n'écrase pas la propriété de la classe parente.L'exemple est tiré de cette page http://docs.python.org/dev/whatsnew/2.6.html#other-language-changes.
[^] # Re: Supposition
Posté par Jean B . Évalué à 1.
Par ce que après:
x existe de nouveau pusique tu as fait un def x. Tu n'as donc plus beoin d'y faire référence via la classe parente.
Ça peut paraître bizarre, mais c'est du aux contraintes du modèle objet de Python: une classe ne peux pas faire référence à elle même dans sa déclaration. Donc le seul moyen de récupérer la référence de la property original c'est de passer par la référence de la classe mère explicitement.
[^] # Re: Supposition
Posté par benoar . Évalué à 2.
Oui. Même si, plus précisément, ici c'est le décorateur qui va au final attribuer la variable x.
Oui. Mais on peut tout à fait faire référence aux variables de cette classe déjà définies : c'est ce qu'il se passe avec les décorateurs, ici.
Non. Comme dit au dessus, on peut très bien récupérer les variables déjà définies dans la classe, c'est comme ça que marche ce mécanisme de « chaînage » des décorateurs. Par contre, on ne peut récupérer les variables des classes parentes qu'en mentionnant le parent explicitement. Ce qui est fait ici avec le premier décorateur de la classe D.
[^] # Re: Supposition
Posté par Jean B . Évalué à 2.
Hum je n'ai pas du être assez explicite car j'ai l'impression que tu n'a fait que me paraphraser ....
[^] # Re: Supposition
Posté par benoar . Évalué à 2.
De la même manière que @x.setter n'écrase pas les autres accesseurs dans la classe C. Et de toutes façons, à sa manière, le @C.x.getter a déjà « écrasé » la variable parente (x) au sens où D l'a maintenant redéfinie (mais en gardant les setter et deleter de C).
Il faut bien comprendre que les trois « accesseurs » dont on parle sont en fait une seule variable python. Pour bien comprendre, il faut déjà bien avoir compris le mécanisme de property, sans les décorateurs : c.f.
help(property)
.Quand x.setter est appelé, cette fonction « mémorise » les autres accesseurs déjà définis et ajoute seulement le setter.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.