ホームページ  >  記事  >  バックエンド開発  >  Python クロージャの詳細な紹介

Python クロージャの詳細な紹介

高洛峰
高洛峰オリジナル
2017-03-26 18:02:011272ブラウズ

コンピュータサイエンスにおいて、クロージャ(Closure)とはLexical Closure(Lexical Closure)の略称で、自由変数を参照する関数のことです。参照された自由変数は、関数が作成された環境を離れた後も関数とともに残ります。したがって、クロージャは関数とそれに関連する参照環境で構成されるエンティティである、という別の言い方もできます。クロージャは実行時に複数のインスタンスを持つことができ、異なる参照環境と同じ関数の組み合わせによって異なるインスタンスが生成されることがあります。

私は後者を好みます。理由は後で説明します。

では、クロージャのコード構造とは何でしょうか?

Python ではすべてがオブジェクトであり、もちろん関数も含まれます。関数オブジェクトは変数に代入でき、この変数を通じて関数を呼び出すことができます。また、関数オブジェクトをパラメータとして渡したり、関数の戻り結果として使用したりすることもできます。さらに、Python では関数を入れ子にすることができます。

Python は関数オブジェクトに基づいており、クロージャの文法構造のサポートを提供します

最初に例を見てみましょう

def f1():
    name1 = 'Alice'
    name2 = 'Bob'
    def f2():
        print('hello,%s,%s' %(name1,name2))    return f2 


if __name__ == '__main__':
    name1 = 'David'
    name2 = 'Frank'
    func = f1()
    func()
    print(func.__closure__)
    print(func.__closure__[0].cell_contents)
    print(func.__closure__[1].cell_contents)# 输出hello,Alice,Bob
(<cell at 0x03A55CF0: str object at 0x03CBEA20>, <cell at 0x03CBEAD0: str object at 0x03CBEAA0>)
Alice
Bob

関数 f2 は関数 f1 内で定義されており、f1 で定義された変数 name1 と name2 を呼び出します。

f1 は関数オブジェクト f2 を返しますが、返される f2 には実際には f1 に変数 name1 と name2 が含まれていることがコードの実行結果からわかります。

メインプログラムでは、name1とname2が再定義されていますが、関数func実行時の変数値は、使用時の変数値ではなく、定義時の参照環境変数が呼び出されたままです。

要約すると、Python では、クロージャは関数と参照される環境変数を含むコード ブロックです。私はクロージャを関数ではなくコード構造として考える傾向があります。なぜなら、クロージャは初めて呼び出されたときに単にラップされるだけだからです。クロージャの参照環境と内部関数を合わせて取得し、内部関数を実行せずに関数オブジェクトとして返します。 この関数オブジェクトが呼び出されると、内部関数関数が実行されます。

参照環境変数の値は、関数オブジェクトのクロージャプロパティに保存されます。クロージャにはタプルが含まれています。このタプルの各要素はセル型のオブジェクトです。最初のセルに「Alice」が含まれていることがわかります。これは、クロージャを作成したときの環境変数 name1 の値です。これは、上記のコードの結果からわかります。

それでは、百科事典のクロージャの説明を振り返ってみましょう。

次に、別の例を示します:

# 此例子转自伯乐在线def line_def(a, b):
    def line(x):
        return a * x + b    return lineif __name__ == &#39;__main__&#39;:
    func = line_def(2, 3)
    print(func(5))# 输出13

この例では、関数行と環境変数 a、b がクロージャを形成し、異なる直線関数を取得するには、a、b の値を変更するだけです。カプセル化を改善するということは、パラメータ a と b にのみ注意を払う必要があり、内部直線の実装については気にしないことを意味します。

クロージャの最大の特徴は、外部関数の変数を内部関数にバインドし、その変数(つまりクロージャ)をバインドした後に関数を返すことができることです。このとき、環境(外部関数)であっても構いません。クロージャを生成したものは解放されましたが、クロージャはまだ存在します。

クロージャの主な用途はデコレータですが、クロージャは関数を渡します。これは次回書きます。

以上がPython クロージャの詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。