0

私はデコレータについて学んでいます。質問があります。このデコレータ関数call_counterでは、別の関数が定義されて返され、関数funcがデコレータ関数のパラメータとして渡されます。これが完了するとPythonクロージャ:関数内で定義された関数は、1レベル上の変数にアクセスできますか?

def call_counter(func): 
    def helper(*args, **kwargs): 
     helper.calls += 1 
     return func(*args, **kwargs) 

    helper.calls = 0 

    return helper 

、私たちは、このように任意の関数の外からhelper.callsにアクセスすることができます。

@call_counter 
def addition(x, y): 
    return x + y 

print(addition.calls) 
addition(1, 2) 
print(addition.calls) 

出力:

私の質問がある
0 
1 

、どのようにすることができますhelper.calls変数をcall_counter関数が呼び出されて終了した後にメモリに存在しますか?私が理解する限り、のメモリにはhelper.callsが存在します。しかし、call_counterの実行が終了した後に変数にアクセスできるかどうかはわかりません。

+2

'calls'は' call_counter'ではなく 'helper'に関連しています。 –

+1

'.calls'は単に' call_counter'によって返された新しい 'helper'関数オブジェクトの属性です。実際のクロージャ「マジック」は、新しい 'addition'関数が' func'引数として 'call_counter'に渡された' addition'の元のバージョンを呼び出すことができるということです。 –

答えて

1

callshelperの財産であり、それはhelper死ぬまで生きるだろう、とhelperはあなたが言ったように、それはaddition名の下に住むことになる、ために死ぬつもりはありません。

+0

'helper'関数はどのようにして消滅しますか?私が "助手"を "殺す"ことを望むなら、どうすればいいのですか? – Sahand

+0

私はそれを見て、「追加」(または「ヘルパー」)は、私が「追加」を呼び出すたびに生き、死にます。だから、毎回メモリから '呼び出し 'を取り除いてはいけませんか? – Sahand

+0

私の混乱はおそらく、 'calls + = 1'の代わりに' helper.calls + = 1'と書くときに何が起こるのか理解していないことに由来していると思います。これについてはどこで読むことができますか? – Sahand

0

call_counter関数は、呼び出されるたびにhelperという名前で新しいオブジェクト(関数)を作成します。そして、call_counter関数は、新しく作成されたオブジェクトを返します。デコレータの動作として、それは基本的にない:

def addition(x,y): 
    return x+y 
addition = call_counter(addition) 

は、だから今、返されたオブジェクト(以前helperという名前の関数は)additionの下に格納されています。

関連する問題