2017-02-07 12 views
0

私はpython 3でデコレータを書くことを試みています。これは基本的に、関数が呼び出される回数をカウントしています。 は、ここに私のコードです:デコレータのpython呼び出しシーケンス

def call_counter(func): 
    def helper(x): 
     helper.calls += 1 
     return func(x) 

    helper.calls = 0 

    return helper 


@call_counter 
def succ(x): 
    return x + 1 

for i in range(10): 
    print(succ(i)) # <--- ?? 

私は理解してどのようにデコレータの作品が、私はここに持っている唯一の混乱は初めて(x)はデコレータ@call_counterリターンで関数を取得しますSUCCするために呼び出すことです。 ここでの主な混乱は、forループ内のシーケンシャルコールがここでどのように起こるかを理解できていないことです。

最初の呼び出しから返された関数(この場合はヘルパー)が得られたら、どのように流れますか?

ここで、forループ内でsucc(0)、succ(1)などが呼び出されますが、どのように機能しますか? forループが1で追加されるたびに、最初の呼び出しから返された同じ戻り関数を再利用するか、またはデコレータが呼び出されますか?

答えて

1

デコレータは、それが満たされたときに1度だけ適用され、その後にsuccのすべての呼び出しは返された同じ機能を使用します。helper。あなただけの代わりにそれを呼び出すforループ内に関数オブジェクトを印刷した場合

これは見ることができます:フローは、helper引数xで、毎回ストレートフォワードと呼ばれている

for i in range(10): 
    print(succ) 
<function call_counter.<locals>.helper at 0x7fe4d05139d8> 
<function call_counter.<locals>.helper at 0x7fe4d05139d8> 
# ... so on, ten times. 

ました funcに渡されます。

+0

デコレータを透明にしたい場合は、 'functools.wraps'を使用することができます。 – khachik

+0

ありがとうジムが、私はあなたのsucc()の中に印刷(succ)を置くことを意味し、ループのための右ではないと思いますか?しかし、私はあなたのポイントを得る。 – skyrocker

関連する問題