Pythonの閉バッグは何ですか?

3818 ワード

目次
  • スコープ
  • 閉パケットの定義
  • 閉包作用
  • まとめ
  • 2018.4.15は関数の役割ドメインに対する理解内容を更新した.
    1.作用域
    役割ドメインはプログラム内の変数の有効範囲を限定し、1つの関数に対して、その内部定義の変数の役割ドメインはこの関数体の内部であり、関数が呼び出されると、この変数は解析されます.簡単に言えば、関数で定義された変数をローカル変数と呼び、関数内部でのみ参照できます.
    次の例では、ローカル変数が関数外にアクセスできないことを示します.
    In [9]: def f1():
       ...:     a = 1
       ...:
    
    In [10]: print(a)
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
     in ()
    ----> 1 print(a)
    
    NameError: name 'a' is not defined
    

    すべての関数の外で定義された変数は、関数によってアクセスできます.
    In [12]: b = 1
    
    In [13]: def f2():
        ...:     print(b)
        ...:
    
    In [14]: f2()
    1
    

    また、Pythonは関数のネストをサポートするため、関数の役割ドメインの原則に従って、内関数は外関数定義の変数にアクセスすることができる.
    In [37]: def f1():
        ...:     x = 1
        ...:     def f2():
        ...:         print(x)
        ...:     f2()
        ...:
    
    In [38]: f1()
    1
    

    2.閉パッケージの定義
    前のコードを少し変更します.
    In [50]: def f1():
        ...:     x = 1
        ...:     def f2():
        ...:         print(x)
        ...:     return f2
        ...:
    
    In [51]: m = f1()
    
    In [52]: n = f1()
    
    In [53]: m == n
    Out[53]: False
        
    In [54]: m()
    Out [54]: 1
    
  • 上記の例から、f 1が返すたびに関数が異なることがわかる.
  • には、In[54]:x()というコードにおいて、関数f 1()が呼び出されるにつれてパラメータxの役割ドメインが終了したにもかかわらず、関数mは正常にパラメータxを参照することができ、これは、埋め込み関数が外部関数のパラメータを参照することができ、これらのパラメータの役割ドメインが外部関数の呼び出しが終了するにつれて埋め込み関数によって参照できることを示している.

  • 上記の例では、Wiki百科事典の閉パッケージの定義を再導入します.
    コンピュータ科学では、クローズド・パッケージ(英語:Closure)は、文法クローズド・パッケージ(Lexical Closure)または関数クローズド・パッケージ(function closures)とも呼ばれ、自由変数を引用した関数である.この参照される自由変数はこの関数とともに存在し,それを創造する環境を離れても例外ではない.もう1つの説では,閉パケットは関数とそれに関連する参照環境とを組み合わせたエンティティであると考えられる.
    インライン関数で参照する外部変数を変更する場合は、インライン関数で変更する変数にnonlocalキーを使用して宣言する必要があります.
    In [58]: def creatCounter():    #                    
        ...:     i = 0
        ...:     def count():
        ...:         nonlocal i     # nonlocal                              
        ...:         i += 1
        ...:         return i
        ...:     return count
        ...:
    
    In [59]: f = creatCounter()
    
    In [60]: f()
    Out[60]: 1
    
    In [61]: f()
    Out[61]: 2
    
    In [62]: f()
    Out[62]: 3
    

    3.閉包作用
    閉パケットはグローバル変数を使用することを避け、閉パケットはいくつかのデータと関数を関連付けることを可能にします.これはクラスに似ています.オブジェクト向けプロセスでは、いくつかのプロパティを定義し、いくつかのメソッドに関連付けます.1つのメソッドのみを使用するクラスを定義する場合は、閉パッケージメソッドを使用して実装できます.また、クローズドパックはアクセサリーにも重要です.
    関数が閉じているかどうかを判断するには、closureプロパティを表示します.閉じている場合は、cellオブジェクトからなるメタグループを返し、cellオブジェクトごとにcell_を表示します.contentsプロパティは、閉パケット参照の自由変数の値を返します.次の例を示します.
    In [41]: def add(x,y):
        ...:     def f(z):
        ...:         return x+y+z
        ...:     return f
        ...:
    
    In [42]: d = add(5,5)
    
    In [43]: d(9)
    Out[43]: 19
    
    In [44]: d(1)
    Out[44]: 11
    
    In [45]: d.__closure__      #    __closure__  
    Out[45]:
    (,
     )
    
    In [46]: for i in d.__closure__:
        ...:     print(i.cell_contents)   #     cell      —— cell_contents  
        ...:
    5
    5
    
  • cell_contentsは、変数がcell_に格納されているため、局所変数が関数から離れた後も関数の外にアクセスできることを説明した.contentsが当たった.

  • 4.まとめ
  • pythonの役割ドメインルールでは、変数を作成すると必ず現在の役割ドメインに変数が作成されますが、変数にアクセスしたり変更したりするときは、まず現在の役割ドメインで変数を検索し、一致する変数が見つからない場合は、閉じた役割ドメインで順次上へ検索します.
  • インライン関数でnonlocalキーワードを使用して外部変数を宣言し、インライン関数が外部変数を変更できるようにします.
  • 閉パケットは、自由変数を参照した関数である.
  • 閉パケットは、実行時に複数のインスタンスを有することができ、異なる参照環境と同じ関数の組合せは、異なるインスタンスを生成することができる.
  • 閉パッケージには、内部関数のコードと、必要な外部関数の変数の参照が含まれています.参照される変数を上値(upvalue)と呼びます.
  • 関数が閉じているかどうかを判断し、closure属性
  • が存在するかどうかを確認できます.
  • closureプロパティは、複数のcellオブジェクトを含むメタグループであり、各cellオブジェクトのcell_contentプロパティは、それぞれ自由変数の値を表します.

  • 结语:この文章は勉强のノートとして、ネット上の先辈の文章やその他の资料を参考にしているので、大量に引用する可能性があります.