※この記事はUdemyの
「現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル」
の講座を受講した上での、自分用の授業ノートです。
講師の酒井潤さんから許可をいただいた上で公開しています。
##■デコレーターの基本
#####◆デコレーターを使わずに書くと
def add_num(a, b):
return a + b
print('start')
r = add_num(10, 20)
print('end')
print(r)
start
end
30
add_num()
を呼び出すだけでなく、その前後などでなにか追加で行いたいとき、「デコレーター」を用いることができる。
#####◆デコレーターを使って書くと
def print_info(func):
def wrapper(*args, **kwargs):
print('start')
result = func(*args, **kwargs)
print('end')
return result
return wrapper
def add_num(a, b):
return a + b
f = print_info(add_num)
r = f(10, 20)
print(r)
start
end
30
*args
については、52. 位置引数のタプル化
**kwargs
については53. キーワード引数の辞書化 を参照。
#####◆デコレーターの一般的な使い方
上の様に記述すると、デコレーターとして使っているということがわかりにくい。
なので、一般的にデコレーターを用いるときには以下の様に記述する。
def print_info(func):
def wrapper(*args, **kwargs):
print('start')
result = func(*args, **kwargs)
print('end')
return result
return wrapper
@print_info
def add_num(a, b):
return a + b
r = add_num(10, 20)
print(r)
start
end
30
@
を使ってデコレーターの関数を指定してやることで、その関数を使ってデコレートできる。
##■デコレーターを複数使う場合
#####◆デコレーターをかける順番
もう1つデコレーターの関数を書いて、2つとも使ってみる。
def print_more(func):
def wrapper(*args, **kwargs):
print('func: ', func.__name__)
print('args: ', args)
print('kwargs: ', kwargs)
result = func(*args, **kwargs)
print('result: ', result)
return result
return wrapper
def print_info(func):
def wrapper(*args, **kwargs):
print('start')
result = func(*args, **kwargs)
print('end')
return result
return wrapper
@print_info
@print_more
def add_num(a, b):
return a + b
r = add_num(10, 20)
print(r)
start
func: add_num
args: (10, 20)
kwargs: {}
result: 30
end
30
このようにデコレーターを指定した場合、
print_info
の中に print_more
が内包されているのがわかる。
今度は2つのデコレーターの順番を入れ替えてみる。
def print_more(func):
def wrapper(*args, **kwargs):
print('func: ', func.__name__)
print('args: ', args)
print('kwargs: ', kwargs)
result = func(*args, **kwargs)
print('result: ', result)
return result
return wrapper
def print_info(func):
def wrapper(*args, **kwargs):
print('start')
result = func(*args, **kwargs)
print('end')
return result
return wrapper
@print_more
@print_info
def add_num(a, b):
return a + b
r = add_num(10, 20)
print(r)
func: add_num
args: (10, 20)
kwargs: {}
start
end
result: 30
30
今度は、print_more
の中に print_info
が内包されている。