Pythonデコレータについて
はじめに
Pythonのデコレータについて理解したので書いていきます。
デコレータとはなにか?
関数に機能を付け足す事を簡単にする機能のこと。
デコレータを理解しよう
デコレータを理解するためには4つのステップがあると思っています。
(1) 関数の引数に関数を入れられる。
def function1():
print("HelloWorld")
def function2():
print("NewWorld")
def function3(f):
print("A")
f()
print("B")
function3(function1)//function1にはカッコを付けない
//出力
//A
//HelloWorld
//B
function3(function2)//function2にはカッコを付けない
//出力
//A
//NewWorld
//B
(2) 関数をreturnできる
def function1():
def function2():
print("Hello")
return function2//カッコつけない
x=function1()
//xにはfunction2が入っている
x()
//出力
//Hello
function1()()
//これは上のx()と同じ
//出力
//Hello
(3) 1と2を使い関数を装飾する
def function1(f):
def function2():
//if文などを書いてもヨシ
print("++++++++++")//装飾
f()
print("++++++++++")//装飾
return function2
def function3():
print("World")
x=function1(function3)
//xは関数
x()
//出力
//++++++++++
//World
//++++++++++
function1(function3)()
//上のx()と同じ
//出力
//++++++++++
//World
//++++++++++
(4)デコレータ
def function1(f):
def function2():
//if文などを書いてもヨシ
print("++++++++++")//装飾
f()
print("++++++++++")//装飾
return function2
@function1
def function3():
print("World")
function3()
//出力
++++++++++
World
++++++++++
(3)と(4)でのfunction1とfunction2は全く同じ。
デコレータを使うメリット
@をつけるだけで普通のコードをそのまま使っているように感じることができる。
装飾されているのがわかりやすい
デメリット
なにが装飾されているかわかりにくい(function1とfunction2は普通隠されているため)
補足
(1)function1で関数を返す必要がなさそう?
def function1(f):
print("++++++++++")
f()
print("++++++++++")
def function2():
print("HelloWorld")
function1(function2)
//出力
++++++++++
HelloWorld
++++++++++
この場合だと出力が同じで関係なさそうですが、よく考えてみると引数に問題が生じてしまいます。
def function1(f):
print("++++++++++")
//Sはどこ?
f(S)
print("++++++++++")
def function3(S:str)->str:
print(S)
return S+"World"
S="Hello"
function1(function3)
この状態だとf(S)に値を入れられません。
しかし関数で返すと
def function1(f):
def function2(S:str)->str:
print("++++++++++")
x=f(S)
print("++++++++++")
return x
return function2
def function3(S:str)->str:
print(S)
return S+"World"
S="Hello"
x=function1(function3)(Hello)
//出力
++++++++++
Hello
++++++++++
print(x)
//出力
HelloWorld
となります。
可変長引数
def function1(f):
def function2(*args,**kwargs)->str:
print("++++++++++")
x=f(args)
print("++++++++++")
return x
return function2
def function3(S:str)->str:
print(S)
return S+"World"
S="Hello"
x=function1(function3)(Hello)
function2の引数を(*args,**kwargs)とどんな関数でも受け取れます。
終わりに
デコレータを使うと関数に機能を追加するのが楽!
間違ってたりしたら教えてください
pythonのコメントは#でした。
(直さないのは直すのが面倒だけ)