2017-05-26 1 views
0

Je veux écrire un décorateur pour montrer le vrai nom des fonctions décorées, mais quelque chose ne va pas quand j'écris de cette façon.Python: programme pour obtenir le vrai nom de la fonction décorée

from functools import update_wrapper 

def decorator(d): 
    def _decorator(f): 
     update_wrapper(d(f), f) 
     return d(f) 
    return _decorator 

@decorator 
def add2(f): 
    def _add2(x,y): 
     return f(x,y)*2 
    return _add2 

@add2 
def add(x,y): return x+y 

Si je veux obtenir le nom d'ajouter (x, y), il montre comme ceci:

>>>print add.__name__ 
_add2 

Mais si je fais peu de changement au décorateur func comme ceci:

def decorator(d): 
    def _decorator(f): 
     return update_wrapper(d(f), f) 
    return _decorator 

Le résultat sera correct:

>>>print add.__name__ 
add 

Je suis vraiment confus à ce sujet. Dans mon esprit, cela ne devrait pas faire une telle différence parce qu'ils sont presque les mêmes.

+0

Je ne suis pas sûr que je comprends très bien la question. Est-ce que "pourquoi functools.update_wrapper garde mon nom de fonction inchangé, alors que mon décorateur homebrew ne le fait pas?" une reformulation précise? – ymbirtt

+0

Utilisez 'wraps' https://docs.python.org/2/library/functools.html#functools.wraps –

+0

@KlausD:' update_wrapper() 'est l'implémentation sous-jacente de' wraps' .. –

Répondre

0

Vous appelez d(f)deux fois, et chacun crée un nouvel objet fonction wrapper; ce sont des copies indépendantes et nouvelles. Vous n'appliquez que update_wrapper() au premier résultat et renvoyez le second.

Appelez-le une fois:

def decorator(d): 
    def _decorator(f): 
     wrapper = d(f) 
     update_wrapper(wrapper, f) 
     return wrapper 
    return _decorator 
+0

Un grand merci! C'est exactement ce que je veux savoir. – BlackCatXJ