ホームページ >バックエンド開発 >Python チュートリアル >関数型プログラミングを学ぶPython入門

関数型プログラミングを学ぶPython入門

黄舟
黄舟オリジナル
2016-12-16 16:36:371073ブラウズ

1 はじめに

私が初めて関数型プログラミングに触れたのは、分散コンピューティングを学んでいた時でした。当時は、map/reduce についてあまり知識がなく、原理についてもあまり理解していませんでした。 Python での関数型プログラミングは、map/reduce の予備的な理解とみなすこともできます。いわゆる関数型プログラミングは本質的にプロセス指向プログラミングに起因しますが、その考え方は数学的計算に非常に近いです。これは一般的なプログラミング パラダイムよりも抽象的であり、純粋な関数型プログラミング言語で記述された関数には変数がありません。入力が決定される限り、出力も決定されます。もう 1 つの特徴は、関数自体をパラメータとして別の関数に渡し、関数を返すことができることです。

2 高階関数

Python では、関数名は本質的に変数です。関数名を変数に割り当て、この変数を通じて関数を呼び出すことができます。 Python を使用したプロセス指向プログラミングでは、変数を含む関数は非常に一般的な設計ですが、変数が関数の場合、この変数を含む関数は高階関数と呼ばれます。

高階関数の簡単な例:

def fun(n):
return n+1

def highorder(x, y, f):
return f(x)+f(y)

上記で定義されているhigherorderは高階関数であり、他の関数をパラメータで受け取ることができる関数です。

3つのMap/Reduce

上記の高階関数の基礎があれば、Map/Reduceを簡単に理解できるようになりました。 Map 関数は 2 つのパラメーターを受け取ります。1 つは関数で、もう 1 つは Iterable です。 Map は関数を Iterable の各要素に順番に適用し、結果を新しい Iterator として返します。

以下の例を見てください:

def fun(n):
return n*2

m=map(fun, [1,2,3,4,5])PRint(m)

E:Studypython> ; python hello_python.py
[2, 4, 6, 8, 10]

Map は関数 fun をリストの各要素に順番に適用し、[2,4,6,8,10] を取得します。

楽しい関数を定義するのが面倒な場合は、次のように lambda を使って簡略化できます:

m=map(lambda n:n*2, [1,2,3,4,5])

Reduceの使い方をもう一度見てください。 Map と同様に、Reduce も関数をシーケンスに順番に適用しますが、この関数は 2 つの関数を受け取る必要があります。 Reduce は、最初の 2 つのパラメーターの結果とシーケンスの次の要素に関数を適用します。

Reduce を使ってシーケンスの合計演算を実装してみましょう。次の例を参照してください:

def add(x,y):
return x+y

r=reduce(add, [1,2,3,4, 5] ])
print(r)

E:Studypython>python hello_python.py
15

そのラムダバージョンは:

r=reduce(lambda x,y:x+y, [1,2,3 ,4 ,5])

4つの戻り関数

前述したように、関数は変数に代入できるので、関数は変数を返すことができるので、当然関数を返すこともできます。変数を返すことと関数を返すことには大きな違いはありませんが、関数を返すこのメカニズムはアプリケーションで大きな役割を果たします。

次の例を見てください:

def Wrapper(*param):
def calc():
for x in param:
return sum return calc;

f= ラッパー(1,2,3,4,5 )

print(f())

E:Studypython>python hello_python.py
15


不特定の数のパラメータを受け取るラッパー関数wrapperを定義します。この関数を呼び出すと、実際に呼び出されたときに実行される内部定義関数が返されます。また、calc 関数でアクセスされるデータはラッパーによって取り込まれ、これらのパラメーターは calc と一緒に保存されることにも注意してください。これを「クロージャ」と呼びます。

5 クロージャ

初めてクロージャに触れたとき、私はそれをよく理解できませんでした。引き続きパート 4 のコードを例として使用します。

ラッパーは、不定数のパラメータparamを含む関数です。特別なのは、新しい関数 calc もこの関数本体で定義されていることです。この新しい関数の関数本体は、外部関数ラッパーのパラメーターを参照します。つまり、外部関数によって渡されたパラメーターがバインドされているということです。 calc 関数を組み合わせると、新しい関数が形成されます。 param はこの新しい関数の設定情報と考えることができます。設定情報が異なれば、関数の出力も当然異なります。

クロージャをよりよく理解するには、次のコード例を見てください:

def Wrapper(conf):

def calc(n):

return conf+n

return calc

f1=wrapper(1)
f2=wrapper ( 2)

print(f1(100))
print(f2(100))

E:Studypython>python hello_python.py
101
102

上記のコードを分析すると、wrapper(1)を呼び出すと関数が返され、この関数の設定情報はconfの値が1であることがわかります。再度wrapper(2)を呼び出すと別の関数が返され、この関数の設定情報ではconfの値は2となっています。したがって、後で f1 と f2 を呼び出すために 100 個のパラメーターを渡すと、得られる結果は 101 と 102 になります。根本的な理由は、2 つの関数の構成情報が異なることです。

外部関数のすべての情報が内部関数によって構成情報として使用されるわけではなく、外部関数のパラメーターのみが内部関数によって構成情報として使用されることに注意してください。外部関数のローカル変数については、設定情報として使用されません。

6 Decorator

Decoratorを発明した当初の目的は、元の関数コードを変更せずに、関数呼び出しの前後にログの印刷などの他の関数を追加することでした。デコレータは本質的に関数を返す高階関数です。コードは次のとおりです:

defdecorator(func):
def Wrapper():
print("Before invoked:")
func() A Print ("呼び出し後:")
ラッパーを返す

Def Func ():
Print ("Func 呼び出し:") python.py
呼び出し前:
Func 呼び出し:
呼び出し後:


上記のコードは func のデコレータを定義しており、このデコレータを呼び出すと、必要なコードをこの関数に追加して func を呼び出します。しかし、ここには問題があります。つまり、func を直接呼び出すこともできましたが、今度は f が呼び出されるということです。 Python では関数を変数に割り当てることができるため、この問題を解決するのは簡単です。f を func に変更するだけです。以下に示すように:

func=decorator(func)
func()

Python は、このメカニズムを実装するための構文 @ を提供します。 func の前に @decorator を追加するだけです。これは func=decorator(func) を実行するのと同じです。これにより、関数を追加した後に同じ名前を使用してコードを呼び出すという問題が解決されます。以下に示すように:

defdecorator(func):

def Wrapper():
print("Before invoked:")
func()

print("After invoked:")

return Wrapper

@dec orator
def func ():
print("Func invoked:")

func()


さらに、デコレータにパラメータを追加する方法と、ラッパーの __name__ 属性を func に変更する方法もあります。ここで説明します。



7 部分関数

部分関数とは何ですか?部分関数は、関数にデフォルトのパラメーターを追加する関数です。 Python では、functools.partial を使用して関数の部分関数を生成できます。 Python の int() を例に挙げます。 int() 関数はデフォルトで 10 進数に変換します。 8 進数に変換する部分関数を生成したい場合は、次のように実装できます。 )

int8=functools.partial(int,base=8)

print(int8('12345'))

8つのまとめ


この記事では主に関数型プログラミングにおけるいくつかの基本概念について話します。個人的に一番分かりにくいのはDecorator、特にいわゆる設定情報だと感じています。間違いがある場合は、メッセージを残してください。 ! !

上記は Python の入門学習のための関数型プログラミングの内容です。その他の関連記事については、PHP 中国語 Web サイト (www.php.cn) に注目してください。

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