関数の上についてる@マークもといデコレータについて
細かい事は置いといて、デコレータってどんなことしてるの?という記事です。
実例
内容はひとつの関数で書けというものですが、とりあえず実例を出します。
コード
#デコレータを定義
def greet(func):
def inner(*args,**kwargs):
print("こんにちは。")#1
result = func(*args,**kwargs)#2
print("よろしくお願いします。")#3
return result#4
return inner
#使い方
@greet
def myName(name):
print(f"私は{name}です。")
return "挨拶 終"
print(myName("ねこでべろん"))
結果
こんにちは。
私はねこでべろんです。
よろしくお願いします。
挨拶 終
解説
myName()
の上に@greet
を付ける事でmyName()
をgreet()
でデコレートしました。
#1 デコレータが「こんにちは。」と出力
#2 myName()
を実行。名前を出力し返り値をresultに格納
#3 デコレータが「よろしくお願いします。」と出力
#4 返り値を返す(print
で出力される)
このような流れで実行されます。
どんなイメージなのか
少しコードを変えます
コード
#デコレータを定義
def greet(func):
def inner(*args,**kwargs):
print("こんにちは。")
result = func(*args,**kwargs)#関数本体
print("よろしくお願いします")
return result
return inner
#@greet
def myName(name):
print(f"私は{name}です。")
return "挨拶 終"
#print(myName("ねこでべろん"))
print(greet(myName)("ねこでべろん"))
結果
こんにちは。
私はねこでべろんです。
よろしくお願いします。
挨拶 終
解説
さっきとほとんど変わりません。@greet
をやめて、
myName("ねこでべろん")
をgreet(myName)("ねこでべろん")
に変えただけです。そしてこれこそがデコレータの本質です。
greet(myName)
によってfunc
にmyName
が代入されたinner
という関数が返ってきます。よってgreet(myName)("ねこでべろん")
はinner("ねこでべろん")
を実行している事になります。
その結果inner内の処理が順に実行されていきfunc
ではmyName
が代入されているのでその処理が行われます。
つまり、@greet
はこの一連の流れを簡単に記述するために使われているということです。
ところで*args
、**kwargs
って何者
メインではないので少しだけ紹介程度に。
*args
、**kwargs
は可変長引数と呼ばれるものです。
*args
が普通の引数、**kwargs
が引数名を指定した引数をそれぞれ格納します。
args
、kwargs
の文字であることに意味はありません。重要なのは*
と**
です。argsはarguments、kwargsはkeyword argumentsの略語で慣例的に使われています。
ちょっとした実例
def task(day,task,limit):
print(f"{day}は{task}を{limit}までにする")
task("土曜日","買い物",limit="15時")
"土曜日"
と"買い物"
は*args
、limit="15時"
は**kwargs
に格納されます。
一般化したデコレータ
一応貼っときます
def decorater(func):
def inner(*args,**kwargs):
toDo()
result = func(*args,**kwargs)
toDo()
return result
return inner
最後に
私的にわかりやすい解説を作りました。
ミスなどあればお知らせください。