🪄

デコレータとは(関数の上の@)

2024/01/08に公開

今回はデコレータについて解説します。

初めに

デコレータとは、関数の動きを装飾する関数のことです。
通常の関数の上に@をつけて使用します。

デコレータ

デコレータは関数を装飾するための機能です。
複数の関数に同じ処理を追加することができます。

まずはデコレータと同じ動きの関数を、デコレータを使用せずに定義します。
文章を出力する関数の前後に、startとendを追加で出力するようにします。

  • デコレータ不使用
# デコレータになる関数
def start_end(func):
    def add_start_end():
        print('start')
        func()
        print('end')
    return add_start_end

def print_apple():
    print('これはりんごです')

start_end(print_apple)()    
# start
# これはりんごです
# end

(デコレータになる)関数start_endは、受け取った関数(func)と追加処理(print)をパッケージした新しい関数(add_start_end) を返していることがわかります。

デコレータは、これと同じ処理を、関数の名前を変えず簡潔に記述するものです。

  • デコレータ使用
# デコレータになる関数
def start_end(func):
    def add_start_end():
        print('start')
        func()
        print('end')
    return add_start_end

# デコレータ使用
@start_end
def print_apple():
    print('これはりんごです')

print_apple()    
# start
# これはりんごです
# end

応用

ここでは、デコレートされる関数が引数や戻り値を持つ場合のコードを紹介します。

  • 引数を持つ場合
def start_end(func):
    def add_start_end(_text):
        print('start')
        func(_text)
        print('end')
    return add_start_end

# デコレータ使用
@start_end
def print_text(text):
    print(text + '!')
    
print_text('これはりんごです')
# start
# これはりんごです!
# end

※ 関数内部など、特定のスコープ内部でのみ使用される変数に、習慣として_(アンダーバー)をつけて表記することがあります。

  • 引数と返り値を持つ場合
def start_end(func):
    def add_start_end(*args, **kwargs):
        print('start')
        x = func(*args, **kwargs)
        print('end')
        return x
    return add_start_end

@start_end
def add_text(text):
    print('テキストに ! が追加されました')
    return(text + '!')

text = 'これはりんごです'
print(text)
added_text = add_text(text)
print(added_text)
# これはりんごです
# start
# テキストに ! が追加されました
# end
# これはりんごです!

まとめ

このように、関数と何かしらの処理をパッケージ化して新しい関数にするという処理を、簡単に記述する方法をデコレータと呼びます。
デコレータを使用しないコードと、使用しているコードを比べると、内部の処理が分かりやすいと思います。

それでは今回はここまでになります。読んでいただきありがとうございました!

Discussion