研究ノート:関数型プログラミングのpython3

個人的な使用へのアクセスが間違っている場合にのみ、また私を修正してください。

これは、関数型プログラミングである抽象的なコンピューティング・プログラミングモデル。

関数型プログラミング機能

図1に示すように、機能ではなくコマンドとして計算。

図2に示すように、純粋に機能的なプログラミング言語で書かれた関数は、変数ではありません。

図3は、高次関数、簡潔なコードをサポートします。

Pythonは関数型プログラミングは、次の機能をサポートしてサポートしています

1、純粋に機能的なプログラミングではない:変数が可能になります。

2は、サポート高階関数を:関数も変数として渡すことができます

3、サポートのための閉鎖:クロージャとは、関数を返すことができるようになります。

4、を限定的にサポート無名関数

  • 高次機能

    直接定義:受信機能は、引数として機能することができます。

    彼は説明し始めました

    • 変数は関数を指すことができます

      これは、関数自体が変数に割り当てることができることを意味します

      a = abs
      
      print(abs)  # output:<built-in function abs>
      print(a)    # output:<built-in function abs>

      割り当てが成功したので、それはまた、呼び出すことができないのですか?

      a = abs
      
      print(a(-10))       # output:10

      objk、説明変数は、a今を指すabs関数自体。呼び出しa()関数を呼び出すとabs()完全に同じ

    • 関数名は変数です

      一般的には、関数名は、関数を指すように変数であることを意味しています。absこの変数ポイントabs機能。

      それはあなたがあれば、あるabsを指す他の関数、それはabs()されますされない関数の絶対値。

      abs = len               # 把abs这个变量指向len函数
      
      print(abs)              # 此时abs它就是一个len函数,<built-in function len>
      print(abs(10))          # 你想要去求绝对值,是会报错的。
      print(abs([1,2,3]))     # 而是需要你求长度。3前面两

    それは端的に指摘しておかなければ。

    変数は、関数、より高次の関数であるパラメータとして別の関数を受信することができる機能を指すことができるので

    最も簡単な高階関数を体験

    import math
    
    def sqrt_add(x, y, f):
        return f(x) + f(y)
    
    print(sqrt_add(25, 9, math.sqrt))
    # output:8.0
  • Pythonは内蔵の4高階関数

    • 地図()

      この機能は、それが受信機能反復可能にmap入来配列の機能が順次に印加される各要素

      そして、新しいイテレータとして結果を返します。はい、それはオブジェクトが返さされたマップのイテレータ

      特定のデータを取得するnext()方法。それはまたできるlist()機能します。

      def f(x):
          return x * x
      
      print(list(map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])))
      # output:[1, 4, 9, 16, 25, 36, 49, 64, 81]
      
      # 首字母大写,后续字母小写的规则
      def format_name(s):
          return s[0].upper() + s[1:].lower()
      
      print(list(map(format_name, ['adam', 'LISA', 'barT'])))
      # output:['Adam', 'Lisa', 'Bart']
    • 削減()

      この関数は、パラメータや受信map()などを。

      しかし、行動とmap()異なるreduce()入ってくる関数fは、2つのパラメータを受けなければならないreduce()ためlist、繰り返し呼び出される各要素

      機能ではf、最終的な結果値を返します。

      直角を合計することによって、その理解を容易にします。もちろん、それが直接順番に理解するためにPythonの合計()、と合算することができます。

      from functools import reduce
      
      def f(x, y):
          return x + y
      
      print(reduce(f, [1, 3, 5, 7, 9]))
      # output:25
      # 还可以接收第三个参数,作为计算的初始值。
      print(reduce(faa, [1, 3, 5, 7, 9], 100))
      # output:125
      
      # 第二个例子,求积函数
      def prod(x, y):
          return x * y
      
      print(reduce(prod, [2, 4, 5, 7, 12]))
      # 3360
    • フィルタ()

      この関数は、パラメータや受信map()などを。この関数fの役割は、各要素について決定戻るTrueまたはFalse、もし

      True、それはその要素を保持します。

      はい、返された結果とmap()、それはイテレータの一部です。

      # 从一个list [1, 4, 6, 7, 9, 12, 17]中删除偶数,保留奇数
      
      def is_odd(x):
          return x % 2 == 1
      
      print(list(filter(is_odd, [1, 4, 6, 7, 9, 12, 17])))
      # output:[1, 7, 9, 17]
      
      # 删除None或者空字符串
      def is_not_empty(s):
          return s and len(s.strip()) > 0
      
      print(list(filter(is_not_empty, ['test', None, '', 'str', '  ', 'END'])))
      # output:['test', 'str', 'END']

      見ると、filter()この関数は資格のふるい要素からの配列を返します。

    • ソート()

      コアのランキングアルゴリズムは、2つの数の大きさを比較することです。それは、文字列や辞書それがある場合は?数学のサイズであることを、意味がありません。

      抽象関数で比較します。

      • リストの並び替え

        print(sorted([23, -454, 11, -6, 5]))
        
        # output:[-454, -6, 5, 11, 23]
      • 許容可能なkeyカスタムの並べ替えを実装するための機能。

        print(sorted([23, -454, 11, -6, 5], key=abs))
        
        # output:[5, -6, 11, 23, -454]
        # key指定的函数将作用于list的每一个元素上,并把返回的结果进行排序。
      • ASCII比較の大きさに応じて、文字列をソートします。

        今ケースを無視することを提案し、ソートされた、私たちは小文字に変更し、全体最初の文字列を必要としません。

        前の例によれば、単にによってkey受信された機能を処理します。

        print(sorted(["harden", "Durant", "jordan", "curry", "O'Neal"], key=str.lower))
        
        # output:['curry', 'Durant', 'harden', 'jordan', "O'Neal"]

        要約すると:sorted()ソート機能の本質は、マッピング機能を実装することです。

  • リターン機能

    • 戻り値として機能

      直接の例では、分析します

      def f(x):
          print("run f_function ...")
          def g():
              print("run g_function ...")
              return x
          return g
      
      print(f(5))
      # output:
      run f_function ...
      <function f.<locals>.g at 0x0000017364A0BF28>
      # 当调用f函数时,返回的并不是x的值,而是g函数。
      
      # 要去调用g函数,才会返回x的值
      print(f(5)())
      # output:
      run f_function ...
      run g_function ...
      5 is ok

      この例では、関数f順番には、関数を定義gし、内部の機能gリファレンス外部関数fパラメータとローカル変数。

      ときにf関数が返しg、パラメータや変数が返される関数に格納されています。これは呼ばれる「閉鎖」

    • クロージャ

      クロージャの特性は、関数によって返ささらに参照の外側の関数のローカル変数パラメータ

      シンプルに見えるが、それは使用することがまだ難しいのを。

      今、あなたは閉鎖して機能を実装してみましょう、算出しました1x12x23x3

      def count():
          fs = []
          for i in range(1, 4):
              def f():
                   return i*i
              fs.append(f)
          return fs
      
      f1, f2, f3 = count()
      
      print(f1(), f2(), f3())

      あなたの望ましい結果が1,4,9です。私はそう願っています。実際の出力は9,9,9です

      その理由は、ときにあるcount()機能は三つの機能、iが3となっている参照変数の三つの機能の値を返します。あなたはそれを呼び出すために行くときです

      f1() - >戻り値は9です。

      したがって、関数戻り、変数または変数の後続の変更が発生したループを参照しません

      上記の機能を修正するには

      def count():
          fs = []
          for i in range(1, 4):
              def f(i):
                  return lambda : i*i
              fs.append(f(i))
          return fs
      f1, f2, f3 = count()
      
      print(f1(), f2(), f3())

      オリジナルはreturn i*i置き換えreturn lambda : i*i使用するlambda無名関数を。

      その理由は、変わらない値と一緒に結合機能を同じパラメータです。

  • 無名関数

    map()例としての機能、再計算f(x)方法は、関数を定義する前に、= X 2。

    def f(x):
        return x * x
    
    print(list(map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])))

    今の方法は、直接書き込みで匿名関数

    print(list(map(lambda x: x*x, [1, 2, 3, 4, 5, 6, 7, 8, 9])))

    明らかに、lambda x: x * xその関数f()

    キーワードラムダは、コロンが前に、匿名関数を表すx関数を表すパラメータを

    匿名関数は制限があり、それが唯一の表現で、戻り値は、式の結果であり、リターンを書いていません。

    もちろん、匿名性は関数オブジェクトで、変数に代入して、機能を呼び出すために変数を使用することができます。

  • デコレーター

    前提の本来の機能を変更することなく、それにダイナミックな新機能呼ばれる「デコレータ。」

    これは、高階関数によって新しい関数を返します

    def f1(x):
        return x * 2
    def new_fn(f):
        def fn(x):
            print("call " +  f.__name__ + " ()")
            return f(x)
    
        return fn
    
    g1 = new_fn(f1)
    print(g1(5))
    
    # 这种调用方式的结果:f1的原始定义函数被彻底隐藏了。
    f1 = new_fn(f1)
    print(f1(5))

    ビルトインのPython @構文は、デコレータの呼び出しを簡素化することです

    @new_fn == f1 = new_fn(f1)

    • いいえ参照デコレータありません

      前の説明から、我々はPythonのデコレータの性質は、その後、パラメータとしての機能を受け入れ高階関数である知っています

      新しい関数への復帰後。

      究極の組み合わせ機能を導入すると、スパイラル述べました。

      from functools import reduce
      
      def log(f):
          def fn(x):
              print 'call ' + f.__name__ + '()...'
              return f(x)
          return fn
      
      # 首先是factorial函数要去调用是可型的。因为只要一个参数。
      @log
      def factorial(n):
          return reduce(lambda x,y: x*y, range(1, n+1))
      print(factorial(10))
      
      # 那如果add函数也要去调用这个装饰器就会报错,因为有两个参数,不匹配。
      @log
      def add(x, y):
          return x + y
      print(add(1, 2))
      

      してみましょう@log適応機能を定義した任意のパラメータは、使用することができます*argsし、**kw任意の数の引数は、常に通常の通話ことを確実にするために、。

      改正

      def log(f):
          def fn(*args, **kw):
              print('call ' + f.__name__ + '()...')
              return f(*args, **kw)
          return fn
    • パラメータ化デコレータ

      def log(prefix):
          def log_decorator(f):
              def wrapper(*args, **kw):
                  print('[%s] %s()...' % (prefix, f.__name__))
                  return f(*args, **kw)
              return wrapper
          return log_decorator
      
      @log('DEBUG')
      def test():
          pass
      print(test())

      この層3は、ネストされています。あなただけがこのテンプレートに基づいて書くことに行くことができ、通常は3層のループを取るパラメータ化デコレータを理解する必要があります。

      ここについての簡単な話です。

      @log('DEBUG')
      def test():
          pass
      
      # 这个定义相当于是    
      test = log('DEBUG')(test)
      # 再进行转换
      log_decorator = log("DEBUG")
      test = log_decorator(test)
      # 再进行转换就是
      log_decorator = log("DEBUG")
      @log_decorator
      def test():
          pass
      
      # 所以,带参数的log函数首先返回一个decorator函数,再让这个decorator函数接收test并返回新函数。

      理解するかどうかにかかわらず、参照は現在、装飾、インスタンスのコード実行の流れで解決される予定。

      最初の実行はlog("DEBUG")、返すlog_decorator関数で、関数呼び出しが戻る、パラメータはtest機能、リターンを

      最終的な値は、あるwrapper機能。

    • パーフェクトデコレータ

      実際には、上記の2つの方法は基本的に逃げる、なぜ完璧な、なぜなら本来の機能に加えてデコレータので、オリジナルの手紙

      関数名の数は、新しい関数の関数名になります。一例としてよりも、test関数名はなりwrapper

      あなたはできる__name__.py関数名を取得します。これは、コード依存の関数名のような、失敗することを意味します

      test.__doc__そして、他の属性。本来の機能が必要とされる__name__他に属性をコピーするwrapper()機能。

      便宜上のPython、書く必要wrapper.__name__ = f.__name

      wrapper.__doc__ = f.__doc__このような動作。同様に、直接モジュールに。

      functoolsこのツールレプリケーション・プロセスを完了します。

      import functools
      
      def log(f):
          @functools.wraps(f)
          def fn(*args, **kw):
              print('call ' + f.__name__ + '()...')
              return f(*args, **kw)
          return fn
      
      def log(prefix):
          def log_decorator(f):
              @functools.wraps(f)
              def wrapper(*args, **kw):
                  print('[%s] %s()...' % (prefix, f.__name__))
                  return f(*args, **kw)
              return wrapper
          return log_decorator

      これらは、デコレータの一部を修正しています。図から分かるように、さらにフロント機能に書き込む方法に関する。

  • 部分的な機能

    言及したfunctools多くの機能は、のいずれかの部分関数であるモジュール。

    バイアス機能はしている関数呼び出し削減困難を。

    私は、関数呼び出しの困難さを軽減するために、パラメータのデフォルト値を設定することで、チャプター機能に言及しました。

    上述関数の内部int()機能を、バイナリ変換してもよいです。しかし、デフォルト値は10進数です。

    各呼び出しを避けるためにint(x, base=2)、我々は関数を記述します。カスタマイズします。

    functools.partial多くのパラメータの機能は、新しいパラメータ機能の少ないなることができ、少ないパラメータは、作成時にデフォルトを指定する必要があります

    値は、そのので、新しい関数呼び出しの難易度が低減されます。

    import functools
    
    int2 = functools.partial(int, base=2)
    
    print(int2('1000000'))
    # output:64
    print(int2('1010101'))
    # output:85

    あなたは部分関数を作成すると、実際に関数オブジェクト、受信することができます:最後に、これを追加*argsし、**kwこれらの3つのパラメータを。

おすすめ

転載: www.cnblogs.com/lowkeyao/p/11300441.html