2017-05-26 2 views
0

Ich möchte einen Dekorateur schreiben, um den wirklichen Namen der verzierten Funktionen anzuzeigen, aber etwas schief geht, wenn ich auf diese Weise schreibe.Python: Programm, um den echten Namen der verzierten Funktion zu bekommen

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 

Wenn ich den Namen add (x, y) zu erhalten, zeigt es wie folgt aus:

>>>print add.__name__ 
_add2 

Aber wenn ich machen wenig Änderung func Dekorateur wie folgt aus:

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

Das Ergebnis wird richtig sein:

>>>print add.__name__ 
add 

Ich bin wirklich verwirrt darüber. Meiner Meinung nach sollte das keinen Unterschied machen, weil sie fast gleich sind.

+0

Ich bin mir nicht sicher, ob ich voll und ganz die Frage verstehen. Ist "Warum behält functools.update_wrapper meinen Funktionsnamen unverändert, während mein Homebrew Decorator nicht?" eine genaue Umformulierung? – ymbirtt

+0

Verwenden Sie 'Wraps' https://docs.python.org/2/library/functools.html#functools.wraps –

+0

@KlausD .:' update_wrapper() 'ist die zugrunde liegende Implementierung für' Wraps' .. –

Antwort

0

Sie rufen d(f)zweimal, und jeder erstellt ein neues Wrapper-Funktionsobjekt; Dies sind unabhängige, neue Kopien. Sie wenden nur update_wrapper() auf das erste Ergebnis an und geben das zweite Ergebnis zurück.

Nennen Sie es einmal:

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

Vielen Dank! Genau das möchte ich wissen. – BlackCatXJ

Verwandte Themen