ホームページ >バックエンド開発 >Python チュートリアル >Pythonのクロージャとは何ですか?アプリケーションには何がありますか?

Pythonのクロージャとは何ですか?アプリケーションには何がありますか?

不言
不言転載
2018-10-13 14:53:212486ブラウズ

この記事の内容は、Python におけるクロージャとは何ですか?アプリケーションには何がありますか?一定の参考値があるので、困っている友達は参考にしていただければ幸いです。

1. 戻り値としての関数

「クロージャ」を導入する前に、まず戻り値としての関数の状況を理解しましょう。
関数をパラメーターとして受け取るだけでなく、高階関数は関数を結果値として返すこともできます。例えば、先ほど紹介したデコレータでは戻り値として関数を使用しています。

2. 閉鎖

1. 閉鎖の条件と影響

閉鎖とは何ですか?
関数内に別の関数をネストする場合、内側の関数が外側の関数の変数を参照すると、クロージャが発生する可能性があります。
Soクロージャ生成の 3 つの条件 (1 つは必須):

  • 1. 内部関数はネストされている必要があります

  • 2. 内部関数は外部関数の変数を参照する必要があります

  • 3. 外部関数は外部関数の変数を参照する必要があります内部関数を返す

それでは、なぜクロージャを試す必要があるのでしょうか、またその機能は何でしょうか?

  • 1. クロージャは、外部関数のローカル変数に基づいて異なる結果を取得できます。

  • 2. クロージャが実行されると、現在の実行環境は維持でき、実行結果は関数の最後の実行結果に依存します

2. クロージャーの例

栗 1 : シーケンスの合計を求めます

>>> def calc_sum(*args):
...     ax = 0
...     for n in args:
...         ax = ax + n
...     return ax  # 返回变量
...
>>> calc_sum(1,2,3)
6

ただし、すぐに合計結果を取得する必要はなく、後続のコードで必要に応じて計算する場合は、どうすればよいでしょうか。 合計結果を返すことはできませんが、次のように合計関数を返します:

>>>def lazy_sum(*args):
...    def sum():            # sum()是内部函数,可以利用外部函数的参数
...        ax = 0
...        for n in args:    # sum()中使用外部函数的局部变量
...            ax = ax + n 
...        return ax
...    return sum            # 形成闭包,此时,*args保存在返回的函数中
...
>>>f = lazy_sum(1,3,5,7,9)
>>>f          # 此时返回的是求和函数
>>> f()       # 调用函数f()时,才真正计算求和的结果
25
注:

f を実行するときの、lazy_sum() 関数の内部実行シーケンス。 run return sum では、*args が return 関数に格納され、返されるのは sum() 関数です。 f() を実行すると、sum() を実行するのと同じになり、*args が含まれます。

lazy_sun() を呼び出すと、毎回新しい関数が返されますが、同じパラメータを渡しても、f() 呼び出しの結果には影響しません。

2 番目の点を確認してみましょう:

# 但是调用 f1() 与f2()的调用结果互不影响
>>> f1 = lazy_sum(1,3,5,7,9)
>>> f2 = lazy_sum(1,3,5,7,9)
>>> f1
<function lazy_sum.<locals>.sum at 0x013DD618>
>>> f2
<function lazy_sum.<locals>.sum at 0x02F92DF8>
>>> f1 == f2
False
>>> f1() == f2()
True
>>> f1()
25
>>> f2()
25
>>> id(f1())
1627215984
>>> id(f2())
1627215984

説明: f1 と f2 の戻り関数の位置が異なるため、f1==f2 の戻り結果は False になります。 ただし、最終的な実行結果には影響せず、f1()とf2()の実行結果はどちらも25であり、同じ領域を指すid()で確認できます。

栗 2:

def count():
    fs = []
    for i in range(1, 4):
        def f():         # 返回函数f()放在循环里
            return i*i
    fs.append(f)
    return fs
f1, f2, f3 = count()

実際の実行結果は次のとおりです: f1=9 f2=9 f3=9
実際に考えていたものとは少し異なるかもしれません ([1,4 ,9]) 。 f()関数はforループの中に配置されているため、ループ終了時のみ最終的にi=3の実行結果9が返されます。 したがって、return 関数は、ループ変数や、後で変更される可能性のある量を参照しないことが最善です。では、どのように変更すればよいのでしょうか?

def count():
    def f(j):
        def g():
            return j*j      # 形成闭包
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i))      # 一个i值进入后,f(i)立刻被执行,并加入到fs中
    return fs

f1, f2, f3 = count()  # 返回函数g没有引用j
最終結果: [1,4,9] つまり、f1=1 f2=4 f3=

3. 匿名関数 lambda

定義: 匿名関数は、識別子関数名を定義する必要のないタイプの関数またはサブルーチンを指します。 Python では、lambda キーワードを使用して匿名関数を作成できます。


構文: ラムダパラメータ: 式

またはラムダ仮パラメータ 1,..., 仮パラメータ n: 関数 (仮パラメータ), 入力パラメータ 1,..., 入力パラメータ n


注意 : 1. ラムダ関数は任意の数のパラメータを受け取り、単一の式の値を返すことができます;

2. ラムダにはコマンドを含めることはできず、複数の式を返すことはできません。


利点: 1. 関数を定義するプロセスが省略され、コードが合理化されます;

2. 再利用されない一部の抽象関数はラムダで定義できます。

例:

>>> list( map( lambda x: x*x ,[1,2,3] ) )
[1, 4, 9]
ここで、lamdba x : x*x は次のように実装します: def f(x): return x*x 関数。
  • 匿名関数を変数に割り当て、その変数を使用して関数を呼び出すことができます。例:
    >>> f = lambda x:x*x  
    >>> f(5) # 调用
    >>> g = lambda x,y=2 : x*y
    >>> g(2,4)
    8
    >>> g(2)    # 默认y=2
    4
  • 匿名関数を戻り値として返すことができます。例:
  • ###
    return lambda x:x*x

    以上がPythonのクロージャとは何ですか?アプリケーションには何がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。