Python-閉パッケージClosure


うん~予定通り「閉包」~
一、関数を戻り値とする
「閉パッケージ」を説明する前に、関数が戻り値として使用される場合について説明します.高次関数は,パラメータとして関数を受信できるほか,結果値として関数を返すこともできる.たとえば、先に説明したデコレーションでは、関数を戻り値として表示します.
二、閉包
1、閉包を生じる条件及び作用
閉鎖とは何ですか.関数に別の関数がネストされている場合、内部関数が外部関数の変数を参照している場合、閉パッケージが発生する可能性があります.したがって、閉鎖によって生じる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

    注意:
  • lazy_sum()関数の内部実行順序は、fを実行するとreturn sumに実行され、*argsは戻り関数に保存され、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
    .sum at 0x013DD618>
    >>> f2
    .sum at 0x02F92DF8>
    >>> f1 == f2
    False
    >>> f1() == f2()
    True
    >>> f1()
    25
    >>> f2()
    25
    >>> id(f1())
    1627215984
    >>> id(f2())
    1627215984

    説明:f1f2の戻り関数の位置が異なるため、f1==f2の戻り結果はFalseである.しかし、最後の実行結果には影響を及ぼさず、f1()f2()の実行結果はいずれも25であり、id()で表示され、同じ領域を指す.
    栗二:
    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が返される.したがって、戻り関数は、ループ変数や後続の変化可能な量を参照しないほうがいいです.では、どのように修正しますか?
    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]すなわちf 1=1 f 2=4 f 3=9
    三、匿名関数lambda
  • 定義:匿名関数とは、識別子関数名を定義する必要のない関数またはサブルーチンのクラスを指す.Pythonでは、lambdaキーワードを使用して匿名関数を作成できます.
  • 構文:lambda : またはlambda 1,…, n : function( ), 1,…, n
  • 注意:1、lambda関数は、任意の複数のパラメータを受信し、単一の式の値を返すことができる.2、lambdaにコマンドを含めることはできません.返される式は1つを超えてはいけません.
  • 利点:1、関数を定義する過程を省くことができ、コードを簡素化することができる.2、抽象的で重複しない関数はlambdaで定義できます.

  • 例:
    >>> 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

    ❤ thanks for watching, keep on updating...