第二に、高階関数
高度な機能は、英語は高階関数と呼ばれます。
だから、高階関数は何ですか?
前に説明=高階関数とは何か、我々は機能のさらなる理解を行う必要があります!
自然の2.1機能
機能の本質とは何ですか?
最終的には機能と関数名は何の関係ですか?
Pythonでは、すべてのものは、その関数も例外でなく、対象ではありません、オブジェクトです。
本質的には整数で、機能がない本質的な違い、彼らはそれだけで異なるデータ型です!
次のコードを見てください:
def foo():
pass print(foo) # 这里只打印了函数名, 并没有调用 foo 函数 print(abs) # 直接打印内置函数, 而没有调用
説明:
- それは見ることができる結果、ダイレクトプリント機能自体、および機能が定義されているので、より
at
後のメモリ内のアドレスの関数として理解することができます - Pythonは組み込み関数場合は、これは組み込み関数であることを教えてくれます。
- あなたは前の図と同じ機能を想像することができ、単にメモリ内のオブジェクトを表します。
関数名と機能の関係
実際には、関数名と以前の名前は本質的に異なる変数ではない変数名はオブジェクトを指し示す記号で、関数名はオブジェクトを指し示す記号です。
新しい変数に割り当てられた動的な関数名
関数名は、実際にはポインタ変数関数オブジェクトです。
我々はそれその関数オブジェクト変数ポイントを再作成することはできませんので?
答えはイエスです!
def foo():
print("我是 foo 函数内的代码") a = foo print(a) print(foo) a()
説明:
- あなたは、直接印刷ができます
a 和 foo
、彼らは確かに同じ関数オブジェクトを指していることを証明し、まったく同じ結果を - コールは
a()
の実装であるfoo
、彼らは実際にはオブジェクトであるため、関数内のコード。
関数名に再割り当て
関数名は変数名なので、関数の名前は、再割り当てする必要があります!
def foo():
print("我是 foo 函数内的代码") foo = 3 foo()
説明:
関数名が整数に割り当てられているので、そのリコールは例外をスローします。
2.2高階関数
以前の理解を通じて、我々はすでに、関数の名前は、実際には普通の変数名を知っています。
だから、それはまた、意味されていません:関数は、引数として渡され、それすることができますか?
答えはイエスです!
、高階関数で引数としての機能を受け取ることができます!
最も簡単な高次機能の一つ
def foo(x, y, f): # f 是一个函数 """ 把 x, y 分别作为参数传递给 f, 最后返回他们的和 :param x: :param y: :param f: :return: """ return f(x) + f(y) def foo1(x): """ 返回参数的 x 的 3次方 :param x: :return: """ return x ** 3 r = foo(4, 2, foo1) print(r) # 72
説明:
-
ここで
foo
彼は、パラメータとしての機能を受け取るので、高階関数です。 -
foo1
それにパラメータとして渡さfoo
れ、foo
ローカル変数f
受信しfoo
たデータは、その後、最終的に、上を通過するfoo
とf
同時に、同じオブジェクトを指します。
概要
高階関数を書く、それは関数のパラメータは、他の機能を受け取ることができるようにすることです。
パラメータとして関数に、この関数は、高次関数と呼ばれる関数型プログラミングは、このような抽象度の高いプログラミングパラダイムを指します。
戻り値として関数:次関数2.3別の形態より高いです
高次機能に加えて、結果の値の関数が返されたとしても、パラメータの関数として受け付けます。
def foo():
x = 10 def temp(): nonlocal x x += 10 #x=x+10 return x return temp f = foo() print(f()) print(f())
説明:
- 呼び出し
foo()
た関数を、その後、関数を変数に割り当てf
、この時間f
、およびfoo
内部temp
同じ関数オブジェクトに実際に、ポイント。 - 返す関数を呼び出すたびに
foo
、ローカル変数は、x
そのそれぞれ20と30を与えることを二回と呼ばれる、10で増加しています。 - 関数は、クロージャの関数であるアクセスグローバル変数またはローカル変数外部関数を返します。
2.4内蔵高階関数
関数型プログラミング言語の非常に広い範囲の高次関数の使用。
このセクションでは、簡単には、いくつかの一般的な高階関数について説明します。
リストの並べ替え map/reduce
、 filter
など
2.4.1ソートソート()
2.41ソート()デフォルトのソート
これまでのところ、それはリストに精通している必要があります。リストは繰り返し可能、発注されます。
注:また、ここでは反復の整然とした配列と一致する順序は、要素を指します。
しかし、私はこの種を行う方法の一定のルールに従って要素を一覧表示したい場合は?
各list
インスタンスは、方法があるlist.sort()
私たちが仕事を終えることができます。
sort()
使用して、リスト内の各要素のデフォルト<
大きな後の前に比較小さなを。
これは、デフォルトでは、あります升序排列
nums = [20, 10, 4, 5, 3, 9] nums.sort() print(nums)
2.4.2照合順序を変更
例えば、文字列がリストに格納され、場合は、デフォルトはアルファベット順に配置されています。
私たちはケースを無視したい場合でも、配置すること。そして、デフォルトのソートは、私たちのニーズを満たすことができなくなります
この時間は、あなたが使用する必要がありkey
、このパラメータを
key
機能、時間の一種である必要があり、Pythonは関数の戻り値に応じてソートされます。
ss = ["aa", "Aa", "ab", "Ca", "da"] def sort_rule(ele): return ele.lower() ss.sort(key=sort_rule) print(ss)
2.4.3変更降順
デフォルトでは、ルールを追加した後、配置の昇順に使用されています。
降順必要に応じて、追加のキーワードパラメータを必要と reverse
逆の順序であれば平均値は、限りある True
それは降順を意味し、デフォルトは None
ss = ["aa", "Aa", "ab", "Ca", "da"] def sort_rule(ele): return ele.lower() ss.sort(key=sort_rule, reverse=True) print(ss)
2.4.2地図()及びフィルタ()
関数型プログラミング言語は、通常提供map, filter, reduce
3高階関数を。
python3では、 map和filter
まだ機能を内蔵したが、リスト内包とジェネレータ式の導入による、彼らはそれほど重要になります。
そして持つ派生式のリストを生成map和filter
2つの関数の機能を、だけでなく、読みやすくします。
2.4.2.1 map
a = map(lambda x: x ** 2, [10, 20, 30, 40]) print(list(a)) print(type(a))
説明:
map
:関数は、既存の機能と新たな反復は、オブジェクトを生成することができ、反復タイプを使用することであるmap
タイプmap
1パラメータのデータ・タイプ2が反復され、パラメータの関数である。map
取得しデータが反復の種類毎に、パラメータは、機能1に渡され、その後の反復の新しいタイプの各構成要素の関数の戻り値- 繰り返しの複数があるかもしれない、引数の数が増加しますパラメータがあります。
- 要素の新たに生成されたイテレータ型の数、および要素イテレータが一致その最短数であろう。
a = map(lambda x, y: x + y, [10, 20, 30, 40], [100, 200]) print(list(a))
上記の機能を実現するために、リストを下に使用します
マップの多くよりもエレガントのリストを使用するだけでなく、議論を避けるために1
list1 = [10, 20, 30, 40]
list3 = [x ** 2 for x in list1] print(list3)
list1 = [10, 20, 30, 40]
list2 = [100, 200] # 注意:列表推倒中这里是使用的笛卡尔积 list3 = [x + y for x in list1 for y in list2] print(list3)
2.4.2.2 filter
反復のタイプの機能を濾過すること、及びその後の反復の新しい種類を生成することができる既存のことであってもよいです
そして、使用のmap
タイプ、パラメータ1は、戻り値がする関数であり、True
反復的であってもよい新しいタイプに要素を追加します。
list1 = [0, 1, 3, 4, 9, 4, 7] # 把奇数元素取出来 print(list(filter(lambda x: x % 2 == 1, list1))) # 列表推倒的版本 list2 = [x for x in list1 if x % 2 == 1] print(list2)
2.4.2.3 reduce
python 3では、内蔵の機能削減は、直接、もはやありませんが、モジュールに移動functiontools
中に。
reduce
役割は、2つのパラメータの機能を有する各要素に適用される反復配列であることがあります。
例えば:
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
計算され((((1+2)+3)+4)+5)
from functools import reduce
def f(x, y): print("x=", x, "y=", y) return x + y """ 参数1: 具有两个参数的函数 参数1:前面计算过的值 参数2:从可迭代类型中取得的新的值 参数2: 可迭代类型的数据 参数3: x的初始值, 默认是0 """ r = reduce(f, [1, 2, 3, 4, 5], 0) print(r) # 15
サンプルコード:使ってreduce
階乗
from functools import reduce
def factorial(n): """计算n的阶乘 :param n: :return: """ return reduce(lambda x, y: x * y, range(1, n + 1), 1) print(factorial(5)) print(factorial(6)) print(factorial(7))
第三に、閉鎖
関数型プログラミング言語では、クロージャがより重要と強力な機能です。
Pythonはまた、クロージャをサポートしています。
クロージャとは何ですか?
関数は、外部関数のローカル変数を使用している場合、この関数はクロージャです。
特性閉鎖パッケージ:
- クロージャ機能は、彼がローカル変数である外部関数にアクセスすることができます。閉鎖機能は、まだ外側の関数のローカル変数へのアクセスであるため、外側の関数は、上で実行された場合でも、
- クロージャは関数のローカル変数の外部値は、この変数の常に現在の値にアクセス!
3.1クロージャの定義
def outer():
x = 20 def inner(): """ inner 函数访问了外部函数 outer 的局部变量 x, 所以这个时候 inner 就是一个闭包函数. :return: """ nonlocal x x += 10 return x x = 30 return inner # 调用 outer, 得到的是内部的闭包函数 inner 所以 f 和 inner 其实指向了同一个函数对象 f = outer() ''' 调用 f. f是一个闭包函数,所以他访问的总是外部变量的最新的值, 所以 f 执行的时候 x 的值已经是30. 最终返回的是40 ''' print(f())
3.2。クロージャ
非常に強力なクロージャは、いくつかのより適切なシーンがあります!
遅延評価(遅延評価、遅延評価)
def foo(msg):
def say_msg(): print("hello" + str(msg)) return say_msg say = foo("志玲") say()
注:
上記のコードのfoo
機能は、単に、ネストされた関数を宣言し、ネストされた関数に戻ります。
実際には、実際のコードは、ネストされた関数の内部で定義されています。
言葉遣いは、遅延評価の一種であります!
閉鎖ホールドを使用して
関数呼び出しの一連の一定の状態を維持する必要がある場合は、クロージャの使用は非常に効率的な方法です。
シンプルなカウンター:
def count_down(num):
def next(): nonlocal num temp = num num -= 1 return temp return next # 使用前面的函数计数 next = count_down(10) while True: value = next() # 每调用一次就会减少一次计数 print(value) if value == 0: break
このようデコレータなどの他のアプリケーションがありますが、
第四に、デコレータ
シナリオの適用は、デコレータの閉鎖です。
デコレータは何ですか?
関数が定義されている場合、この関数は、関数の前提のソースコードを変更せずに、いくつかの機能を追加する必要があり、今回はデコレータを使用することができます。
デコレータの機能は基本的にあり、その主な目的は、他の関数やクラスをパッケージ化されています。
パッケージの主な目的は、オブジェクトパッケージの動作を変更し、強化するために透明です。
4.1定義デコレータ
装飾方法で使用することができるクラスでも使用することができます。
現在、我々は唯一の方法デコレータを検討します
実際には、デコレータとJavaアノテーションビットのように、しかし、Javaの注釈ロットより使いやすく。
私たちは関数が与える場合はhello
デコレータの方法の拡張構文を使用して、次のとおりです。
@strong
def hello(): print("我是 hello 函数中的代码")
説明:
- 上記の装飾的な機能の必要性を使用して行を追加する
@
デコレータを追加するために @
デコレータ続いだったstrong
もちろん、あなたは任意の名前に設定することができ、。strong
デコレータは、本質的に彼の受信機機能の関数であり、hello
引数として、及びで置換する機能返すhello
(もちろんを、置換されなくてもよいです)。hello
デコレータ後、同等のhello
機能では、次のコードを交換し使用しています。hello = strong(hello)
- コールでは
hello
、とき、実際には、呼び出されたstrong()
関数が戻ります。
def strong(fun): # fun 将来就是被替换的 hello def new_hello(): print("我是装饰器中的代码, 在 hello 之前执行的") fun() print("我是装饰器中的代码, 在 hello 之后...执行的") return new_hello @strong def hello(): print("我是 hello 函数中的代码") # 这里调用的其实是装饰器返回的函数. hello()
デコレータはシンタックスシュガーです
厳密に言えば、デコレータ構文は単なる砂糖です。
デコレータは、そのパラメータの装飾の関数である関数です。
要約すると、デコレータの主要な特徴は、他の機能の中に装飾的機能を交換することで、 第二の特徴は、ロード時に大きな装飾的な機能モジュールが直ちに実行されます。