Pythonのデコレーターを完全解説!基礎から応用まで学べる実践ガイド

この記事は広告を含みます。

Pythonのデコレーター完全解説!初心者から上級者まで使える実践テクニック

Pythonの「デコレーター」という機能を知っていますか?デコレーターは、関数やクラスの動作を簡単に拡張できる強力な仕組みです。

この記事では、デコレーターの基本から応用までを徹底解説します。。


デコレーターとは?

デコレーターとは、関数の前後に処理を追加するための仕組み です。 Pythonでは、関数を引数として受け取り、新しい関数を返す「高階関数」を利用してデコレーターを実装します。。

例えば、ログを記録する処理を関数の前後に追加したい場合、デコレーターを使うとスマートに実装できます。


デコレーターの基本構文

Pythonでデコレーターを作る基本構文を見てみましょう。

def my_decorator(func):
    def wrapper():
        print("前処理: 関数を実行する前に動作")
        func()
        print("後処理: 関数を実行した後に動作")
    return wrapper

@my_decorator  # デコレーターを適用
def my_function():
    print("メインの関数が実行されました")

my_function()

実行結果

前処理: 関数を実行する前に動作
メインの関数が実行されました
後処理: 関数を実行した後に動作

このように、@デコレーター名 を関数の前に記述することで、デコレーターを適用できます。

デコレーターの実用例

1. 関数の実行時間を測定するデコレーター

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"関数 {func.__name__} の実行時間: {end_time - start_time:.5f} 秒")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(2)
    print("処理が完了しました")

slow_function()

このデコレーターを使えば、関数の実行時間を簡単に測定できます。

2. ログを記録するデコレーター

def log_function(func):
    def wrapper(*args, **kwargs):
        print(f"関数 {func.__name__} が呼び出されました")
        result = func(*args, **kwargs)
        print(f"関数 {func.__name__} が終了しました")
        return result
    return wrapper

@log_function
def sample():
    print("サンプル関数の実行")

sample()

これを使えば、関数の呼び出し状況を簡単に記録できます。 この1と、2を使ってFastAPIを定義するとLog設計などに使えると思います。

3. 引数を持つデコレーター

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def say_hello():
    print("Hello!")

say_hello()

このデコレーターでは @repeat(3) のようにして、関数を3回実行することができます。

クラスに適用するデコレーター

関数だけでなく、クラスにもデコレーターを適用できます。。

def class_decorator(cls):
    class NewClass(cls):
        def hello(self):
            print("Hello from decorated class!")
    return NewClass

@class_decorator
class MyClass:
    def hello(self):
        print("Hello from original class!")

obj = MyClass()
obj.hello()

これにより、クラスのメソッドを拡張できます。。

Pythonの標準デコレーター

Pythonにはいくつかの便利な標準デコレーターがあります。

  • @staticmethod → クラス内でインスタンスを作らずに実行できるメソッドを定義
  • @classmethod → クラス自体を引数に取るメソッドを定義
  • @property → ゲッターのように動作するプロパティを定義
class MyClass:
    def __init__(self, value):
        self._value = value

    @property
    def value(self):
        return self._value

    @classmethod
    def class_method(cls):
        print("クラスメソッドが呼ばれました")

    @staticmethod
    def static_method():
        print("スタティックメソッドが呼ばれました")

obj = MyClass(10)
print(obj.value)  # @property によってメソッドのようにアクセスできる
MyClass.class_method()
MyClass.static_method()

まとめ

デコレーターを使えば、関数やクラスの振る舞いを簡単に拡張できます。

  • デコレーターは関数の前後に処理を追加できる
  • @デコレーター名の形で適用できる
  • 高階関数を使って実装する
  • 標準デコレーターも便利に使える
  • デコレーターを活用すれば、コードをシンプルにしつつ、再利用性を高めることができます。。ぜひ活用してみてください!