2017-05-26 10 views
0

装飾された関数の本当の名前を表示するためにデコレータを書いてみたいが、このように書くと何かがうまくいかない。Python:装飾された関数の実名を取得するためのプログラム

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 

私はアドオン(x、y)の名前を取得したい場合は、それは次のように示しています。私はこのようなFUNCデコレータに少し変更を加えた場合

>>>print add.__name__ 
_add2 

しかし:

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

結果が正しいようになります。

>>>print add.__name__ 
add 

私はそれについて本当に混乱しています。私の考えでは、彼らはほとんど同じなので、違いはありません。

+0

私は完全に質問を理解していません。 "なぜ私の自作のデコレータは機能しないのですが、functools.update_wrapperが関数名を変更しないのはなぜですか?"正確な言い換え – ymbirtt

+0

'wraps'を使用https://docs.python.org/2/library/functools.html#functools.wraps –

+0

@KlausD .:' update_wrapper() 'は' wraps'の実装です。 –

答えて

0

d(f)を2回呼び出し、それぞれ新しいラッパー関数オブジェクトを作成します。これらは独立した新しいコピーです。あなたは最初の結果にupdate_wrapper()を適用し、2番目の結果を返します。

は一度それを呼び出します。

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

ありがとう!それはまさに私が知りたいことです。 – BlackCatXJ

関連する問題