編集:私は自分の質問を説明してくれました。私はどのようにクロージャで、その関数は、以前の環境を覚えているようだが混乱していたが、再帰呼び出しでは、名前の更新値を見つけるようだ。私の混乱再帰関数をデコレートする
がThomas Ballinger "Finding closure with closures" talkによって完全に解決されました:変数の
スコープ定義で決定され、変数の値は、実行時に決定されます。
再帰またはクロージャのいずれかを使用すると、名前のバインディングが定義時に定義されましたが、値はその後でも更新できます。
オリジナル質問:
デコレータは、余分な努力なしに再帰関数では動作:
def debug(f):
def new_f(*args, **kwargs):
print('arguments:', *args, **kwargs)
return f(*args, **kwargs)
return new_f
@debug
def f(n):
if n > 1:
return f(n-1)*n # f refers to the decorated version!
else:
return 1
ではなくラインで
f
その
return f(n-1)*n
ポイント
f
の装飾が施されたバージョンに確実にPythonでどのようなメカニズム
元の?
私は関数が定義された時点でそのコンテキストを記憶していると考えました(つまり、クロージャでは、内部関数は外部関数のオブジェクトを使用できます)。しかし、f
が定義されたときに、デコレータがまだ適用されていなかったので、f
の中にの機能f
は永遠に装飾されていないバージョンを参照していますか?明らかに、私は関数スコープ/文脈規則で何かを誤解しましたが、何ですか?
他の場所を指すようにするメカニズムが欠けています。 '@ debug'は、' f = debug(f) 'を呼び出す関数を定義する構文的な砂糖であることを覚えておいてください。 – jonrsharpe