3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonのデコレータのイメージ

Last updated at Posted at 2022-03-15

関数の上についてる@マークもといデコレータについて
細かい事は置いといて、デコレータってどんなことしてるの?という記事です。

実例

内容はひとつの関数で書けというものですが、とりあえず実例を出します。

コード

decorater.py
#デコレータを定義
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で出力される)
このような流れで実行されます。

どんなイメージなのか

少しコードを変えます

コード

decorater.py
#デコレータを定義
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)によってfuncmyNameが代入されたinnerという関数が返ってきます。よってgreet(myName)("ねこでべろん")inner("ねこでべろん")を実行している事になります。
その結果inner内の処理が順に実行されていきfuncではmyNameが代入されているのでその処理が行われます。
つまり、@greetはこの一連の流れを簡単に記述するために使われているということです。

ところで*args**kwargsって何者

メインではないので少しだけ紹介程度に。
*args**kwargsは可変長引数と呼ばれるものです。
*argsが普通の引数、**kwargsが引数名を指定した引数をそれぞれ格納します。
argskwargsの文字であることに意味はありません。重要なのは***です。argsargumentskwargskeyword argumentsの略語で慣例的に使われています。
ちょっとした実例

def task(day,task,limit):
    print(f"{day}{task}{limit}までにする")  
    
task("土曜日","買い物",limit="15時")

"土曜日""買い物"*argslimit="15時"**kwargsに格納されます。

一般化したデコレータ

一応貼っときます

def decorater(func):
    def inner(*args,**kwargs):
        toDo()
        result = func(*args,**kwargs)
        toDo()
        return result
    return inner 

最後に

私的にわかりやすい解説を作りました。
ミスなどあればお知らせください。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?