Python学習記録:関数内関数、クロージャー、デコレーター、ラムダ、ジェネレーター
2020年10月17日
2021年02月21日
プログラム言語Pythonを学んでいます。
その中で、あとで振り返ったときに覚えておいた方が良さそう、ということをピックアップしてまとめます。
1. 関数内関数
関数の中で関数を定義する。
def outer(a, b):
def inner(c, d):
return c + d
r = inner(a, b)
print(r)
outer(1, 2)
結果はこちら
3
outer関数を実行すると、まずその中でplus関数が呼ばれ、rをプリントしている。
使う場面
関数の中でしかその関数を使わない場合。
2. クロージャー
関数そのものを戻り値(return)にする。
# 円の面積を求める関数
def circle_area_func(pi):
def circle_area(radius):
return pi * radius * radius
return circle_area
# パラメータが違う2パターンの関数をクロージャー関数として定義
ca1 = circle_area_func(3.14)
ca2 = circle_area_func(3.141592)
# パラメータが違う2パターンの関数をそれぞれ実行
print(ca1(10))
print(ca2(10))
結果はこちら
314.0
314.1592
使う場面
すぐ実行したくない時。
実行するタイミングを指定したい時。
引数を変えて違う条件で関数を処理したい時。
3. デコレーター
追加処理を定義した関数。
定義した関数名の前に「@」を付けてやると、それをデコレーターであると認識して、実行してくれる。
デコレーター関数の引数に実行したい関数を渡してあげる。
やりたい処理をデコレーターで包み込む。
一回定義してしまえば、使い回せる。
# print_infoがデコレーター関数
def print_info(func):
def wrapper(*args, **kwargs):
print('start')
result = func(*args, **kwargs)
print('end')
return result
return wrapper
# 実行されるのはadd_num関数だが、その前にprint_info関数が呼ばれる
@print_info
def add_num(a, b):
return a + b
r = add_num(10, 20)
print(r)
結果はこちら
start
end
30
使う場面
定義している関数に対して、何らか汎用的な追加処理を加えたい場合。
4. ラムダ
無名関数。
関数をシンプルに書く方法。
# 以下曜日のリストの頭の文字が大文字にする処理を考える
days = ['Mon', 'tue', 'Wed', 'Thu', 'fri', 'sat', 'sun']
# 引数の言葉を、func関数に渡して処理してください、という関数
def change_words(words, func):
for word in words:
print(func(word))
# 関数を別に定義せずに、「ラムダで関数化」したものを引数に放り込む
change_words(days, lambda word: word.capitalize())
結果はこちら
Mon
Tue
Wed
Thu
Fri
Sat
Sun
使う場面
関数を引数として使う必要があるが、新たにそれ用の関数を定義したくないとき。
5. ジェネレーター
yieldで個別の反復処理要素を定義。
繰り返し処理を拡張するもの。
def greeting():
yield 'Good morning'
yield 'Good Afternoon'
yield 'Good night'
g = greeting()
print(next(g))
# 一回処理を抜ける
print("@@@@@@@@@@@@@@@@@@@")
print(next(g))
# 一回処理を抜ける
print("@@@@@@@@@@@@@@@@@@@")
print(next(g))
結果はこちら
Good morning
@@@@@@@@@@@@@@@@@@@
Good Afternoon
@@@@@@@@@@@@@@@@@@@
Good night
使う場面
繰り返し処理の間に処理を挟み込みたい時。
関連記事