クロージャを応用して関数に機能を修飾するデコレータが使える
#デコレータ関数
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(1,2)
print(r)
>>>
start
end
3
print_info()は関数を引数にとりwrapper関数に渡す。
wrapper関数は任意の処理を行ったあと、受け取った関数を呼び出し返り値を返す。
以下の記述と同等の意味を持つ。
#デコレータ関数
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(1,2)
print(r)
>>>
start
end
3
複数のデコレータを重ねる場合は順序によって処理が変わる。
def print_info(func):
def wrapper(*args, **kwargs):
print('start')
result = func(*args, **kwargs)
print('end')
return result
return wrapper
#new
def print_more(func):
def wrapper(*args, **kwargs):
print('func:',func.__name__)
print('args:',args)
print('kwargs',kwargs)
result = func(*args, **kwargs)
return result
return wrapper
@print_info
@print_more
def add_num(a,b):
return a+b
r = add_num(1,2)
print(r)
>>>
start
func: add_num
args: (1, 2)
kwargs {}
end
3
デコレータの順序を逆にすると
#略
@print_more
@print_info
def add_num(a,b):
return a+b
r = add_num(1,2)
print(r)
>>>
func: wrapper
args: (1, 2)
kwargs {}
start
end
3
処理順が変わる。
以下の記述と同等の意味を持つ
#略
def add_num(a,b):
return a+b
f = print_info(print_more(add_num))
r = f(1,2)
print(r)
>>>
start
func: add_num
args: (1, 2)
kwargs {}
end
3
以上