変数と関数
変数は関数を指すことができます:
abs # 这个变量其实是 abs()
print(type(abs))
<クラス 'builtin_function_or_method'>
このように、関数名をパラメータとして渡すことができるそのような関数の定義として、computed(x, y, f)
そのようなことをx
、y
パラメータとして呼び出すためにf
可変ポイントの機能を。
- 関数オブジェクトには
__name__
属性があり、関数の名前を取得できます
def computed(x, y, f):
return f(x) + f(y)
print(computed(-2, -8, abs)) # 计算-2、-8的绝对值之和
10
たとえばcomputed()
、高次関数と呼ばれる可変関数をとるそのような関数。
高次関数
map()
高次関数
反復可能なオブジェクトのすべての要素に関連付ける関数が作成され、Iterator
(iterator)として返され、実行されるのを待ちます。
- この機能は現時点では実行されておらず、この機能はイテレーターが繰り返された場合にのみ実行されます。
result = map(abs, [-1, -2, 3]) # 得到 <class 'map'> 对象
print(list(result)) # 转为列表
[1、2、3]
result
これは、計算値を使用してすべてのリストを変換した不活性オブジェクトですlist()
。
reduce()
高次関数
。これは、この反復可能オブジェクトのすべての要素に関数を適用する機能は、2つのパラメータを受信する必要があり、reduce()
このように実行する:2つの要素を実行することによって得られた結果を取り、実行を継続するためのパラメータとして、次の要素を置き換えます。結果を取得し、最後まで実行のために次の要素を置き換え続けます。
- この時点で関数は実行されています。
たとえば、シーケンスを組み合わせて数値を形成します。
from functools import reduce # 需要导入模块
def fn(x, y):
return x * 10 + y
r = reduce(fn, [1, 2, 3])
print(r)
123
map()
そしてreduce()
使用例:デジタルへの文字列
from functools import reduce
DIGITS = {
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def char2num(s):
return DIGITS[s]
def str2int(s):
return reduce(lambda x, y: x * 10 + y, map(char2num, s))
filter()
高次関数
そして、map()
似ているが、filter()
構成要素を保持するかどうかを選択する関数によって返されるブール値に応じて、フィルタ要素に使用されるリンクを作成する機能です。イテレータオブジェクトを返します。
- 実行されていない怠惰なオブジェクトを返す
# 判断一个数字反过来还是不是它
def is_palindrome(n):
temp = n
m = 0
while temp > 0: # 有大于十位数的位数存在
m = m * 10 + temp % 10 # 取个位数;下一次循环时,将个位数升级,
temp = temp // 10 # 得到个位数以上的数字
return n == m
print(list(filter(is_palindrome, range(1, 100)))) # 打印1~99的回数
sorted()
高次関数
sorted(lista)
リストを並べ替えるには、キーワードパラメータを渡すこともできますkey
。これは、関数の適用後に要素のリストを並べ替えることができる関数です。
- たとえば
sorted(lista, key=abs)
、リストを絶対値で並べ替えます - Pythonは要素を使用して
abs()
から絶対値を取得し、内部は元の順序に従って続行しますが、この種の要素の場合、abs()
後の要素の使用を確認します。
- この関数は、Pythonがソートするための値を返す必要があります。
文字列リストの元の並べ替えは、ASCIIコードに基づいています。
>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']
key
パラメータを使用して、注文時に大文字と小文字を区別しないようにします。
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
# 排序看的是:'bob', 'about', 'zoo', 'credit'
['about', 'bob', 'Credit', 'Zoo']
逆の順序で、3番目のパラメーターを渡すことができますreverse=True
。
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
- したがって、タプルのリストを並べ替えるなど、渡す関数を作成できます。
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
return t[0] # 返回名字,让 Python 内部根据名字排序
L2 = sorted(L, key=by_name)
# 按照 'Bob', 'Adam', 'Bart', 'Lisa' 进行排序
print(L2)
リターン関数
高階関数は、関数を変数として受け取ることも、関数を戻り値として返すこともできます。
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
f = lazy_sum(1, 3, 5, 7, 9)
# 它是:<function lazy_sum.<locals>.sum at 0x101c6ed90>,是一个函数
f() # 执行函数
- ここで
sum()
関数は外部args
にアクセスでき、lazy_sum
return関数sum
、パラメータ、変数が返された関数に格納されている場合、これは「クロージャ(クロージャ)」と呼ばれるプログラム構造が非常に強力です。 lazy_sum()
同じ引数がそうでない場合でも、各呼び出しは新しい関数を返します==
(動作結果がレンジングであるとは言わず、レンジング関数と言います)sum()
freeと呼ばれる外部参照変数の内部関数変数関数- クロージャで参照される自由変数は特定のクロージャにのみ関連しており、クロージャの各インスタンスによって参照される自由変数は互いに干渉しません。
- クロージャインスタンスの自由変数への変更は、クロージャインスタンスの次の呼び出しに渡されます。
- 閉鎖トラップ:
def my_func(*args):
fs = []
for i in range(0,3):
def func():
return i * i
fs.append(func)
return fs
fs1, fs2, fs3 = my_func()
print fs1()
print fs2()
print fs3()
プログラムの結果は、私たちが想像した結果0、1、4ではありません。実際の結果はすべて4です。関数を返さない
ため、共通変数の関数(自由変数クロージャの関数ではない)のすぐ外側で、関数を返す前に2に割り当てられ、それが自由変数になった後。現時点ではすでに2です。return
i
i
return
i
- 注:ループ変数を返す関数を参照しないでください。参照しないと、フォローアップによって変数が変更されます(
return
前面)。
def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
return fs
閉鎖の例:
# 返回一个计数器函数,每次调用它返回递增整数,多个计数器函数之间互不干扰
def createCounter():
n = 0
def counter():
nonlocal n
n += 1
return n
return counter
- 言い換えると、クロージャは、外部関数の変数インスタンスを独立して所有する関数を返すことです。(小さなオブジェクトに似ています)
デコレータ
コード実行フェーズで、既存の関数に関数を動的に追加します。この機能は多くの機能で選択できます。(Javaデコレータモード)
- これは本質的に、関数を返す高階関数です。
オブジェクト指向(OOP)設計パターンでは、デコレータはデコレーションパターンと呼ばれます。OOPのデコレーションモードは、継承と組み合わせによって実装する必要があります。OOPをサポートするデコレータに加えて、Pythonは構文レベルからデコレータを直接サポートします。Pythonのデコレータは、関数またはクラスを使用して実装できます。
このnow()
関数はlog()
、例として印刷ログ関数を追加します。
- 元の関数の前に追加
@log
:
@log
def now():
print("2020-11-23")
この構文は次と同等です。now = log(now)
- プリミティブがなる実行デコレータ関数、変数の関数で置き換え、関数を返すために、後続のデコレータ機能。
now()
機能上の書き込み機能に定義デコレータ。
def log(func): # func 为 now 函数!
def wrapper(*args, **kw): # *args, **kw 接收任意类型的参数
print(f'call {func.__name__}():')
return func(*args, **kw)
return wrapper
デコレータ関数は関数を返すため、内部で返す関数を定義する必要があります。
呼び出す前にログを印刷する:この内部関数に追加する必要のある関数を完了し、を返すときに元の関数を呼び出しますfunc
。
デコレータ関数がパラメータを渡す必要がある場合は、デコレータを返す高次関数をネストする必要があります(他の名前も使用できます)。
# 装饰器函数
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print(f'{text} {func.__name__}():')
return func(*args, **kw)
return wrapper
return decorator
# 原函数
@log('execute')
def now():
print('2020-11-23')
重要:以下@log('execute')
と同等のことを理解するには:
now = log('execute')(now)
- 最初の実行
log('execute')
、実行log()
はdecorator()
関数を返し、次に引数(now)
呼び出しdecorator()
はwrapper()
関数を返します。 - 直感的に、2つの括弧は外側から内側に2つの機能を実行します。
我々が通過しているので、装飾機能の完了後、@
私たちのデコレータ機能を実行し、その後で私たちのデコレータ機能で元の関数を呼び出すことには、この関数の構文に、now = log(now)
、割り当てられている__name__
ことになりますwrapper
。
- 機能的には要件は満たされていますが、関数の署名に依存する一部のコードの実行は失敗します。
import functools
wrapper()
追加の定義では:@functools.wraps(func)
- このコードはrunning:と同等
wrapper.__name__ = func.__name__
なので、完璧です
部分的な機能
ローカルエリアで、関数のデフォルト値を設定します。
int(x, base=10)
:base
デジタルバンド缶を変更することにより、文字列を数字に変換します。
たとえば、設定base
が非常に不便であるたびに、多くの2桁を変換する必要があります。
import functools
# 创建函数变量int2,赋值为:【默认的参数base设置为2】的int函数
int2 = functools.partial(int, base=2)
print(int2('1000000')) #输出: 64
- ここでのパラメーター:最初のパラメーターは設定する関数であり、後者は関数のパラメーターとして置き換えられます(通常の呼び出し関数の規則に従います)
- キーワードパラメータが使用されていない場合、それは位置パラメータです
部分的な英国[ˈpɑːʃl]アメリカの[ˈpɑːrʃl]調整部分的;部分的;不公平