すべてのPythonの閉鎖について知っておく必要があります.



記事議題
この記事では、Pythonでクロージャの概念を説明します.具体的には、次のように調査します.
  • Nested Functions
  • Closure Property

  • 導入
    今、このポストへの警告があります:それは:ファーストクラスの機能の知識を持っている必要があります.あなたがこれについて知らないならば、心配する必要はありません.私はあなたの背中を得た.ちょうど私の記事を表示するか、あなたが観察学習者の場合は、先に行くことができると同様にファーストクラスの機能を見てください.

    Psst.. あなたが急いでいるならば、あなたは代わりにこのポストの
    さあ、始めましょう.

    入れ子関数

    クロージャを理解する前に、入れ子になった関数を知ることは本当に重要です.基本的に、別の関数の中で一つの関数を定義すると、結果として入れ子関数と呼ばれます.ネストされた関数を次のコードスニペットに示します.
    def calculation(number):
        def double(no):
            return no*2
    
        return double(number)
    
    calculation(10)               # 20
    
    上記のコードでは、関数がありますcalculation()number 引数として.その中で別の機能を宣言しましたdouble() また、引数をとるno を返します.no . 最後に、私はcalculation() 関数を呼び出してdouble() 関数.
    さて、上記のシナリオは入れ子関数の古典的な例でした.簡単に各ステップを理解しましょう
  • 通話をするcalculation() パラメータ値10 .
  • インタプリタは内部に飛び込むcalculation() そしてreturn 他の関数にコールするステートメントdouble() 同じパラメータでnumber = 10 . 現在の状態を一時停止します.
  • インタプリタは内部に飛び込むdouble() パラメータ付きno = 10 を返します.no20 . 終了するdouble() 関数.
  • 20 が反映され、一時停止状態が再開される.これは最終的に値を得ている20 .
  • すごい!どのように簡単だったか?さて、親関数の中に複数の入れ子関数を持っているシナリオをカバーしてください.この場合、これらの関数はすべて、親関数return 文.以下の例を示します.
    def calculation(number):
        def double(no):           # executed
            return no*2
    
        def triple(no):           # skipped
            return no*3
    
        def quadruple(no):        # executed
            return no*4
    
        return double(number), quadruple(number)
    
    calculation(10)               # (20, 40) <-- this is a tuple
    
    とてもよく.これはネストされた関数についてのすべてでした.さて、入れ子になった関数を書くのがきちんとした方法であることを教えてください.ネストされた関数を書くためのより専門的でクリーンな方法があり、その方法ではクロージャと呼ばれるプロパティを使用します.

    閉鎖性

    定義によるクロージャプロパティ(単にクロージャ)は、そのスコープ内の値を覚えていることができます.私は、これがあなたの頭の上に方法を行ったかもしれないということを知っています.
    まず第一に、囲んでいるスコープが意味するものを見ましょう.
    def parent():
        def child()
            pass
        pass
    
    上のコードでparent は、child . つまりchildparent それを呼び出します.そうでなければ、child 休眠状態になります.
    では、「囲い込みスコープ内の値」とは何を意味するかを見てみましょう.
    outside1 = "Outside parent func"
    
    def parent(msg):
    
        inside1 = "I am inside parent"
    
        def child()
            pass
    
        inside2 = "I am inside parent"
    
        pass
    
    outside2 = "Outside parent func"
    
    parent("Hello there!")
    
    
    上のコードでoutside1 and outside2 内部ではないparent() したがって、それらは囲みの範囲内にありませんchild() . 一方、inside1 and inside2 内部ですparent() 関数は、child() .
    同様に、child() ? はい、msg 変数.利用できるのでmsg インサイドparent() 関数は、child() .
    最後に、「範囲を囲むことで値を覚えている」という意味を理解しましょう.前の例を見て、そこから移動しましょう.
    def calculation(number):
    
        number2 = 30             
    
        def double(no):
            return no*2
    
        number3 = 50
    
        return double(number)
    
    calculation(10)               # 20
    
    私はより良い理解のために、2つの余分な変数を追加しました.さて、ここでは、以前の観測に従って、すぐに結論を出すことができます.number , number2 , number3 の範囲はdouble() . では、プロパティの状態を閉じてください.

    function objects can remember values in its enclosing scopes and these values can be used within that function.


    つまり、double() 簡単に内部にアクセスすることができますし、任意の方法でも、パラメータとして渡すことなく、使用されるdouble() 関数.これを得なかったか.以下の有効なスニペットをチェックしてください.
    def calculation(number):
    
        number2 = 30             
    
        def double():
            print(f"I can remember: {number},{number2},{number3}")
    
        number3 = 50
    
        return double()
    
    calculation(10)               # I can remember: 10,30,50
    
    注意するdouble() アクセスと変更number , number2 , number3 引数なしで渡されます.さて、これはその範囲内の値を「覚えている」ことができるためです.閉じるこの動画はお気に入りから削除されています.
    今、この記事を終了する前に、我々はクロージャなしで書いた私たちの以前の乱雑なコードをリファクタリングできます.あなたはスタイルの重要な違いを見ているでしょう.
    def calculation(number):
        def double():           # executed
            return number*2
    
        def triple():           # skipped
            return number*3
    
        def quadruple():        # executed
            return number*4
    
        return double(), quadruple()
    
    calculation(10)               # (20, 40) <-- this is a tuple
    
    ルックスきちんとしないですか?パラメータの周り投げても明示的に渡すことはありません.コードは、よりクリーンでプロフェッショナルな方法です.

    応援してくれませんか.
    私と私のコンテンツをサポートしたい場合は、先に行くとそれを検討する.私は非常に感謝します.

  • ホーム:すべての種類の独特のtutos.

  • GitHub : お楽しみに😉