Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente Dernière révision Les deux révisions suivantes | ||
decorateurs_property [2011/04/06 07:39] tyrtamos créée |
decorateurs_property [2011/04/06 08:18] tyrtamos |
||
---|---|---|---|
Ligne 3: | Ligne 3: | ||
===== Problématique ===== | ===== Problématique ===== | ||
+ | Avec les classes " | ||
+ | * de manipuler (lecture/ | ||
+ | * d' | ||
+ | |||
+ | * voire, d' | ||
+ | |||
+ | Voir [[http:// | ||
===== Codes proposés ===== | ===== Codes proposés ===== | ||
+ | Parmi les différents codes possibles, j'en ai retenu 2: | ||
+ | Version avec décorateur: | ||
+ | <code python> | ||
+ | def Property(func): | ||
+ | return property(**func()) | ||
+ | |||
+ | class Maclasse(object): | ||
+ | |||
+ | def __init__(self, | ||
+ | self._x = x | ||
+ | |||
+ | @Property | ||
+ | def x(): | ||
+ | | ||
+ | doc = " | ||
+ | | ||
+ | def fget(self): | ||
+ | return self._x | ||
+ | | ||
+ | def fset(self, x): | ||
+ | self._x = x | ||
+ | | ||
+ | def fdel(self): | ||
+ | del self._x | ||
+ | |||
+ | return locals() | ||
+ | </ | ||
+ | |||
+ | Version sans décorateur: | ||
+ | |||
+ | <code python> | ||
+ | class Maclasse(object): | ||
+ | |||
+ | def __init__(self, | ||
+ | self._x = x | ||
+ | |||
+ | def x(): | ||
+ | doc = " | ||
+ | | ||
+ | def fget(self): | ||
+ | return self._x | ||
+ | | ||
+ | def fset(self, x): | ||
+ | self._x = x | ||
+ | | ||
+ | def fdel(self): | ||
+ | del self._x | ||
+ | |||
+ | return locals() | ||
+ | |||
+ | x = property(**x()) | ||
+ | </ | ||
===== Exemple d' | ===== Exemple d' | ||
+ | |||
+ | Pour bien comprendre comment ça marche, on va créer une classe Test avec un attribut x qui sera manipulé par property. | ||
+ | |||
+ | on va ajouter des ' | ||
+ | |||
+ | Et on va retirer la méthode de destruction de l' | ||
+ | |||
+ | <code python> | ||
+ | class Test(object): | ||
+ | |||
+ | def __init__(self, | ||
+ | self._x = x | ||
+ | |||
+ | def x(): | ||
+ | doc = " | ||
+ | | ||
+ | def fget(self): | ||
+ | print "appel à fget" | ||
+ | return self._x | ||
+ | | ||
+ | def fset(self, x): | ||
+ | print "appel à fset" | ||
+ | self._x = x | ||
+ | | ||
+ | return locals() | ||
+ | |||
+ | x = property(**x()) | ||
+ | </ | ||
+ | |||
+ | Essayons maintenant des appels: | ||
+ | |||
+ | <code python> | ||
+ | a = Test(5) | ||
+ | |||
+ | print a.x | ||
+ | appel à fget | ||
+ | 5 | ||
+ | |||
+ | a.x = 9 | ||
+ | appel à fset | ||
+ | |||
+ | print a.x | ||
+ | appel à fget | ||
+ | 9 | ||
+ | |||
+ | del a.x | ||
+ | # genère une exception: " | ||
+ | </ | ||
+ | |||
+ | On voit bien que les opérations de lecture (print a.x) et d' | ||
+ | |||
+ | On a omit de définir ici la méthode fdel (ce qui interdit la destruction de x), mais on aurait pu aussi omettre de définir la méthode fset (ce qui interdirait tout changement de valeur de x), ou même la méthode fget (ce qui interdirait toute lecture). | ||
+ | |||
+ | Pour le docstring de x, son accès à partir de l' | ||
+ | |||
+ | <code python> | ||
+ | print Test.x.__doc__ | ||
+ | docstring de x | ||
+ | |||
+ | print a.__class__.x.__doc__ | ||
+ | docstring de x | ||
+ | </ | ||
Ligne 17: | Ligne 138: | ||
Amusez-vous bien! | Amusez-vous bien! | ||
+ | < | ||
+ | < | ||
+ | <style type=" | ||
+ | <!-- | ||
+ | body {background-image: | ||
+ | --> | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | </ | ||
+ | </ | ||