Pythonのクロージャ
クロージャの使い方
クロージャでは関数を入れ後にして、外側の関数実行時の引数を保持し後から使用することが出来る。
以下は消費税別に税込み価格を計算するプログラムの例
#税込み価格を計算するプログラムで消費税率別に計算を行いたいケースで使用する
#クロージャでは外側の関数を実行し変数に格納することで後から内側の関数を呼び出すことができる
#関数の中に関数を宣言し外側の関数の引数で受け取った値を内側の関数で使用する
def sample_func(tax):
#内側の関数では外側の関数の引数で受け取った税率を使用して税込み価格を計算する
def wrapper_func(a):
return int(a +tax * a)
#外側の関数では戻り値として内側の関数を返す
return wrapper_func
#外側の関数を呼び出すと内側の関数が戻り値として返される
print(sample_func(0.1)) #<function sample_func.<locals>.wrapper_func at 0x0000019ABFB3C280>
#戻り値として返される内側の関数を変数に格納する
#消費税が10%、8%の場合を想定する
r1 = sample_func(0.1)
r2 =sample_func(0.08)
#後から内側の関数を実行する
print(r1(100)) #110
print(r2(100)) #108Pythonのデコレータ
デコレータの使い方
デコレータでは関数の前後で必ず何かの処理を行いたい場合などに使用することが出来る。
以下は関数内の計算にかかった時間を計測するプログラムの例
関数実行時はデコレーター名のアノテーションを使用することで自動的にデコレーターを実行してくれる。
デコレーターを複数使用するときは上に書いた方から外側で実行されることになるため順番にも気を付ける。
#デコレーターは関数の前後で何か処理を行いたい場合などに使用する
#計算の前後で「start」「stop」と宣言する
#計算にかかった時間を計測する
import time
#外側の関数で実行する関数を引数に受け取る
def sample_func(func):
#どんな関数も実行できるようにタプルと辞書を引数に受け取る
def wrapper(*args,**keywargs):
#前後に実行したいプログラムを記述する
print('start')
#外側の関数の引数で受け取った関数を実行する
r =func(*args,**keywargs)
print('stop')
#関数の実行結果を返す
return r
#内側の関数を返す
return wrapper
def time_func(func):
def wrapper_func(*args,**keywargs):
#プログラム開始時の時間を記録する
time_start = time.time()
r = func(*args,**keywargs)
#プログラム終了時の時間を記録する
time_end = time.time()
#プログラムの開始時-終了時の時間を計算する
time_result = time_end-time_start
print(f'計算にかかった時間は{time_result}秒でした')
return r
return wrapper_func
#実行したい関数
def sum_func(a):
r = 0
for i in range(a):
r +=i
return r
#実行したい関数を引数にして外側の関数を呼び出し戻り値を変数に格納する
a = sample_func(sum_func)
#戻り値の変数を実行する
print(a(100000000))
#アノテーションを付けることで関数を実行した際に自動的にデコレーターを実行してくれる
#上に記述したデコレータが外側で実行されることになるため順番に注意をする
@sample_func
@time_func
def sum_func(a):
r = 0
for i in range(a):
r +=i
return r
print(sum_func(100000000))
#Result####################################
#start
#計算にかかった時間は6.431143045425415秒でした
#stop
#4999999950000000Pythonのラムダ
ラムダの使い方
ラムダは関数を簡易的に書くことが出来る。関数内で簡易な関数を使用する際などに使用する。
構文は lambda 引数:戻り値 で記述する。
以下は引数で受け取った文字列を整形するプログラムの例である。
#ラムダを使用することで関数を簡易的に記述することができる
#配列に入った文字列を全部大文字、全部小文字、先頭文字だけ大文字に変更するプログラム
words = ['apple','banana','orange']
#引数の配列を引数の関数に渡し実行結果を出力する
def sample_func(func,words):
for word in words:
print(func(word))
#ラムダを使用しない例
#引数で受け取った文字列を全て大文字にして返す
def Upper_func(fruit):
return fruit.upper()
sample_func(Upper_func,words)
#ラムダを使用することで引数の関数作成と実行を一行でかける
#引数で受け取った文字列を全て大文字に変更する
sample_func(lambda fruit:fruit.upper(),words)
#引数で受け取った文字列を全て小文字に変更する
sample_func(lambda fruit:fruit.lower(),words)
#引数で受け取った文字列の先頭だけを大文字に変更する
sample_func(lambda fruit:fruit.capitalize(),words)
以上。
