Comments on: Créer un décorateur à la volée http://sametmax.com/creer-un-decorateur-a-la-volee/ Du code, du cul Sat, 07 Nov 2015 11:08:18 +0000 hourly 1 http://wordpress.org/?v=4.1 By: Sam http://sametmax.com/creer-un-decorateur-a-la-volee/#comment-10852 Sat, 13 Jul 2013 14:51:54 +0000 http://sametmax.com/?p=6624#comment-10852 Je me suis fait la même remarque, il faudrait regarder dans le code source pour trouver la réponse, mais j’ai la flemme.

]]>
By: groug http://sametmax.com/creer-un-decorateur-a-la-volee/#comment-10838 Fri, 12 Jul 2013 15:33:55 +0000 http://sametmax.com/?p=6624#comment-10838 Ok, c’est la non-disparition que je n’avais pas comprise. Merci !

Ce que je ne comprends pas (mais que j’accepte), c’est pourquoi, alors que le décorateur @valeur.setter mentionne le nom de la property (valeur), la méthode doit être nommée valeur aussi. Si je change le nom :

@valeur.setter
def valeur_set(self, valeur):
    self._valeur = valeur.strip()

Python me dit qu’il ne trouve pas la méthode valeur_set quand je fais bille.valeur = "foo". Ca paraît un peu redondant. Ca paraîtrait, dans ce cas, plus logique d’avoir un décorateur de nom @property.setter, si c’est pour devoir, de toute façon, nommer la méthode intelligemment.

]]>
By: Sam http://sametmax.com/creer-un-decorateur-a-la-volee/#comment-10836 Fri, 12 Jul 2013 14:48:59 +0000 http://sametmax.com/?p=6624#comment-10836 En fait, on ne créer pas deux méthodes de même nom, car en Python on ne donne pas de nom aux méthodes. Sous le capot, def attache simplement la référence à la méthode à un nom. Quand la seconde méthode est crée, elle est attachée à ce nom et l’ancienne n’est plus attachée à ce nom, mais ici ne disparaît pas pour autant.

En effet, un objet en Python n’est supprimé que dans le cas où aucune référence ne pointe vers lui. Dans notre cas précis, @property garde une référence interne de la méthode et elle n’est pas supprimée.

Pour aller plus loin dans l’explication : @property va créer un descripteur qu’il va placer en lieu et place de l’attribut portant le nom des méthodes. Il va ensuite attacher chaque méthode à ce descripteur. Au final, quand on lit, écrit ou supprime le contenu de l’attribut, on appelle le descripteur, qui lui appelle les méthodes.

Le descripteur a donc une référence pour chaque méthode décorée, ainsi les méthodes ne sont jamais supprimées, et reste accessibles.

Mangez des pommes !

]]>
By: groug http://sametmax.com/creer-un-decorateur-a-la-volee/#comment-10834 Fri, 12 Jul 2013 13:23:28 +0000 http://sametmax.com/?p=6624#comment-10834 Salut Sam & Max ! J’ai découvert votre blog en début d’année, et ma connaissance de Python est un gros gruyère. J’estime qu’il y a plein de choses subtiles que je ne connais pas du langage, et c’est souvent que j’en découvre grâce à votre blog en me disant à chaque fois : p’tain, c’est quand même de la balle, Python. Aujourd’hui ne fait pas exception, alors j’en profite pour une fois pour vous dire un grand merci !

Mais j’ai une question : décorateur différent ou pas, j’étais persuadé qu’il n’était pas possible de créer 2 méthodes du même nom, même si le nombre d’arguments différait. Comment se fait-ce ?

]]>
By: foxmask http://sametmax.com/creer-un-decorateur-a-la-volee/#comment-10831 Fri, 12 Jul 2013 11:42:55 +0000 http://sametmax.com/?p=6624#comment-10831 ok merci

]]>
By: Sam http://sametmax.com/creer-un-decorateur-a-la-volee/#comment-10829 Fri, 12 Jul 2013 10:41:13 +0000 http://sametmax.com/?p=6624#comment-10829 L’interêt d’un décorateur, c’est qu’on peut l’ajouter et le retirer à loisir, et sur plusieurs fonctions.

Si on utilise juste **k, on ne peut plus utiliser le decorateur sur des fonctions avec des paramètres positionnels :

def serializable(func):
 
    # Contrairement à la plupart des décorateurs, on ne va pas retourner
    # un wrapper, mais bien la fonction originale. Simplement on lui aura ajouté
    # des attributs
 
    func.as_json = lambda **k: json.dumps(func(**k))
    func.as_pickle = lambda **k: pickle.dumps(func(**k))
 
    return func
 
@serializable
def get_day_name(day_number, locale, short=False):
    with TimeEncoding(locale) as encoding:
        s = day_abbr[day_number] if short else day_name[day_number]
        return s.decode(encoding) if encoding is not None else s
 
print get_day_name.as_json(0, ('fr_FR', 'UTF-8'))
 
Traceback (most recent call last):
  File "/home/sam/Bureau/functions_as_functions_attributes.py", line 103, in <module>
    print get_day_name.as_json(0, ('fr_FR', 'UTF-8'))
TypeError: <lambda>() takes exactly 0 arguments (2 given)
]]>
By: foxmask http://sametmax.com/creer-un-decorateur-a-la-volee/#comment-10824 Fri, 12 Jul 2013 07:41:23 +0000 http://sametmax.com/?p=6624#comment-10824 pourquoi :

func.as_json = lambda *a, **k: json.dumps(func(*a, **k))

et pas ?

func.as_json = lambda **k: json.dumps(func(**k))
]]>