2016-10-22 5 views
0

私は、以下のリンクからPythonでデコレータの概念を学んでいた。Pythonのデコレータは、どのように関数を生成しますか?

http://www.python-course.eu/python3_decorators.php

私はそれで次のコードスニペットのための基本的な疑問があります。このページで

def f(x): 

    def g(y): 
     return y + x + 3 
    return g 

nf1 = f(1) 

nf2 = f(3) 

print(nf1(1)) 

print(nf2(1)) 

を、それは最後の2つのラインの出力がそれぞれ「5」および「7」になると書かれている。 しかし私が見ることができるように、私たちは 'x'の値を渡すだけです、どこから 'y'の値を取得しますか?どのように出力を計算するために 'Y'に値を割り当てるのですか?

+0

これはデコレータではなく、クロージャです。デコレータは引数として*関数*を取り、入力に基づいて新しい関数を返します。クロージャは、(大まかに)それが定義されているスコープ内のローカル変数の値を「覚えている」関数です。 2つの概念は、デコレータがしばしば元の関数を呼び出すクロージャを返すという点で関連しています。 – chepner

+0

つまり、 'g'はクロージャであり、' f'は単にクロージャを返す関数です。 – chepner

答えて

1

機能fは、gという名前の新しい関数を作成して返します。

ので、このコードはx=1x=3を渡すことによって、2つのg関数を作成します:

nf1 = f(1) 

nf2 = f(3) 

その後(nf1nf2に格納されている)g関数は引数y=1と呼ばれています。たぶん

print(nf1(1)) 

print(nf2(1)) 

(またはそうでないかもしれない)彼らは相当物を書いていればもっと理解できるはずだった:

print(f(1)(1)) # x=1, y=1 
print(f(3)(1)) # x=3, y=1 
+0

y = 1の理由についてもう少し分かりますか? –

+0

@itpdusra 'nf1' **は**' g'です。なぜなら 'f'は' g'を返すからです。関数 'g'は1つの引数yをとるので、' nf1'は 'g'なので' nf1'は引数yをとります。その部分が分かりやすくなると思っています;)本当に難しい問題は、 'nf1'と' nf2'がどちらも 'g'のとき' x'の値がどう違うかということです。そのためには、[これは閉鎖についてのこの回答](http://stackoverflow.com/a/4020443/389289)を読むのが良いかもしれませんが(これはもう少し高度なトピックです)。 – zvone

関連する問題