2017-04-21 5 views
0

私はPythonでデコレータを学びたいと思っています。私はそれを得ると思うたびに、私はこのような問題に遭遇します。 my_funcのprintステートメントが表示されず、代わりに「None」が返される理由を理解できません。私のラッパーのreturn文にfuncを含めると、return (func, wrapper)タプルオブジェクトが呼び出し可能でないというエラーが発生します。この例で何が問題になっていますか?なぜこのpythonデコレータは元の関数の値を出力しないのですか?

def my_dec(func): 
    def wrapper(): 
     decoration = "decorated" 
     print(decoration) 
    return wrapper 

@my_dec 
def my_func(): 
    a = "Original" 
    print (a) 

print(my_func()) 
+0

予想される出力と実際の出力を含めることで、質問を改善することができます。 – quamrana

答えて

4

あなたのwrapperに包まれfuncを呼び出すことはありませんしています。例えば、呼び出しを追加します:

def my_dec(func): 
    def wrapper(): 
     decoration = "decorated" 
     print(decoration) 
     # Call the decorated function and return what it returns 
     return func() 

    return wrapper 

@my_dec 
def my_func(): 
    a = "Original" 
    print (a) 

print(my_func()) 

は今(func()implicitly returns None以降)を生成します:

decorated 
Original 
None 

私は私のラッパーreturn func, wrapperの私のreturn文でfuncが含まれている場合、私はタプルを言ってエラーが出ますオブジェクトは呼び出し不可能です。 is (roughly) equivalent to just doingを飾ることを忘れないでください

def my_dec(func): 
    def wrapper(): 
     decoration = "decorated" 
     print(decoration) 

    # Now `my_dec` returns a tuple instead of a function 
    return func, wrapper 

エラーはあなたのような何かをやってから来るんだろうあなたのmy_dec()デコレータは今タプル(func, wrapper)の代わりに、ラッパー関数を返さ

def my_func(): 
    ... 

my_func = my_dec(my_func) 

だから、 my_func()に電話しようとすると、実際には my_funcに割り当てられたタプルを「呼び出す」ことを試みています。あなたはFUNC 見えるようにラッパー機能を更新する、update_wrapper()を呼び出すための便利な機能である、functools.wrapsを使用する方法を学ぶ必要があります良い対策として

from functools import wraps 

def my_dec(func): 
    @wraps(func) 
    def wrapper(): 
     decoration = "decorated" 
     print(decoration) 
     return func() 

    return wrapper 

それがなければ、あなたは」取得dは:

In [4]: print(my_func.__name__) 
wrapper 

とラップと:

In [9]: print(my_func.__name__) 
my_func 

__doc__のような他の有用な属性もコピーします。

+0

これは今私にとって理にかなっています。どうもありがとうございました。私はfunctools.wrapsも今探っていきます。 –

関連する問題