💡
Pythonにおけるラッパー関数のテクニック:functools.wraps
結論
ラッパー関数作成時はfunctools.wraps
を使う!!
通常のラッパー関数と弊害
ラッパー関数とは、元の関数を書き換えることなく、機能を追加する関数である。
ラッパー関数は例えば以下のように書く。
def trace(func):
def wrapper(*args,**kwargs):
result = func(*args,**kwargs)
print('Hello') #追加したい処理
return result
return wrapper
@trace
def f(n):
"""nの2乗を返す関数"""
return n**2 #元の処理
これでもラッパー関数として機能するが、f
を呼び出すと以下のように出力される。
<function __main__.trace.<locals>.wrapper(*args, **kwargs)>
このように出力されると、wrapper
を用いていることはわかるが、肝心のf
自体が何か判別できない。
pickle
のdump
でもシリアライズできず、デバックも困難になってしまうので改善が必要である。
functools.wraps
を用いた改善
ラッパー関数を使用しても、関数f
が何かわかるようにするには、以下のようにwraps
を用いてラッパー関数を定義すると良い。
from functools import wraps
def trace(func):
@wraps(func)
def wrapper(*args,**kwargs):
result = func(*args,**kwargs)
print('Hello') #追加したい処理
return result
return wrapper
@trace
def f(n):
"""nの2乗を返す関数"""
return n**2 #元の処理
from functools import wraps
はラップする関数の情報(内部関数の情報)を外部関数に複製する役割を持つ。
つまりf
を(外部から)呼び出したとしてもf
の中身の情報を参照することができる。
このように定義したf
を呼び出すと以下の結果が得られる。
<function __main__.f(n)>
f
の中身を把握するにはhelp
関数を用いればよい。
help
関数の結果が以下であり、Docstringの内容を出力できる。
Help on function f in module __main__:
f(n)
nの2乗を返す関数
ラッパー関数の実例
ラッパー関数の実例は過去こちらで紹介している。
Discussion