Pythonのデコレーター(@アットマーク)は何をしているのか
投稿日: 更新日:
デコレーターとは
デコレーターとは関数を修飾するための関数のことです。
ある関数func1
を関数deco
で修飾するのが以下のコードです。
def deco(func):
def _wrapper():
print("start")
res = func()
print("end")
return res
return _wrapper
@deco
def func1():
print("func1")
return "ret"
print(func1())
実行結果
start
func1
end
ret
動作順番
どのような順番で動作しているのか説明します。
deco
関数が呼び出される。引数にfunc1
が渡される。deco
関数は_wrapper
関数を返す。_wrapper
関数を実行する。関数内のfunc
は手順1で渡されたfunc1
である。_wrapper
関数が値resu
を返す。
このような動作手順になります。
デコレーターを書き換えると以下のコードと同等です。func1
の上にあった@deco
が無くなっていることに注意してください
def deco(func):
def _wrapper():
print("start")
res = func()
print("end")
return res
return _wrapper
def func1():
print("func1")
return "ret"
print(deco(func1)())
deco(func1)()
は混乱しそうです。しかし、よく考えるとdeco(func1)
は_wrapper
関数を返すことに注目すれば、deco(func1)()
は_wrapper()
と考えれます。
引数を渡す
関数に引数を渡す
func1
に引数を渡すこともできます。その場合_wrapper
に*args
と**kwargs
を引数に指定します
def deco(func):
def _wrapper(*args, **kwargs):
print("start")
res = func(*args, **kwargs)
print("end")
return res
return _wrapper
@deco
def func1(v1):
print(f"v1: {v1}")
return "ret"
print(func1(123))
実行結果
start
v1: 123
end
ret
デコレーターに引数を渡す
デコレーターに引数を渡すこともできます。その場合さらに引数を受け取る関数deco
で覆います。
def deco(add):
def _deco(func):
def _wrapper(*args, **kwargs):
print("start")
res = func(*args, **kwargs)
res += add
print("end")
return res
return _wrapper
return _deco
@deco(321)
def func1(v1):
print(f"v1: {v1}")
return v1
print(func1(123))
実行結果
start
v1: 123
end
444
参考文献
Pythonのデコレータを理解するための12Step https://qiita.com/_rdtr/items/d3bc1a8d4b7eb375c368
(最終閲覧:2022/08/26)