「クロージャ」では、外部関数を変数に代入した後、ローカル変数がグローバル変数になります。

この問題は次の「クロージャ」の例から出ていますが、まず結果を推測してみましょう。

def funX():
    x = 5
    def funY():
        nonlocal x
        x += 1
        return x

a = funX()
print(a())
print(a())
print(a())

消す:

6
7
8

なぜこのローカル変数 x がグローバル変数と同じなのか疑問に思われるかもしれません。x は呼び出されるたびに 5 に再初期化されるべきではないでしょうか?

実際、注意深く見てみると、 a = funX() の場合、 a 変数が再割り当てされない限り funX() は解放されないことがわかります。これは、ローカル変数 x が再初期化されないことを意味します。

理解を容易にするために、外部関数に別のコード print(x) を追加します。

def funX():
    x = 5
    print(x)
    def funY():
        nonlocal x
        x += 1
        return x
    return funY

a = funX()
print(a())
print(a())
print(a())

もう一度実行してみると、ローカル変数 x がグローバル変数「になる」理由が表示されます。

5
6
7
8

それでも理解できない場合は、コードを再度変更すると、次のことがわかります。

funX() を変数 a に代入する過程で "5" が生成されます。
文を短くしましょう:
funX() を変数 a に代入する過程で "5" が生成されます。割り当てプロセス中に生成される

つまり、システムが a = funX() を実行すると、funX() 関数が呼び出され、print(x) 命令が実行され、値 funY が返されます。このとき、a の値は funY であり、内部関数 funY() は条件を暗黙的に示しますx=5

funY() を独立した関数とみなした場合、a() を 3 回呼び出すプロセスは、次の命令を実行することと同じになります。

>>>x = 5
>>>def funY():
        global x
        x += 1
        return x
    return funY

>>>funY()
6
>>>funY()
7
>>>funY()
8

したがって、問題の核心は、a = funX() は代入処理であり、a 変数が再代入されない限り funX() は解放されず、ローカル変数 x は 5 に初期化されません。

おすすめ

転載: blog.csdn.net/A_No2Tang/article/details/113785130
おすすめ