Pythonでデコレータとコンテキストマネージャを効率的に利用する方法

この記事では、Pythonでよく用いられる高度なテクニックである「デコレータ」と「コンテキストマネージャ」について、具体的なコード例とその解説、応用例を含めています。

目次

デコレータとは

デコレータは、関数やメソッドの振る舞いを修飾(デコレート)するためのPythonの特性です。具体的には、既存のコードに手を加えることなく関数の挙動を変更したい場合に使用します。

基本的なデコレータの作成と使用方法

Pythonでデコレータを作成する基本的な方法は以下の通りです。

# デコレータの定義
def my_decorator(func):
    def wrapper():
        print("何か前処理")
        func()
        print("何か後処理")
    return wrapper

# デコレータの使用
@my_decorator
def say_hello():
    print("こんにちは")
    
say_hello()

この例では、`say_hello()` 関数を `my_decorator` でデコレートしています。これにより、関数が呼ばれる前後に任意の処理(ここでは前後にテキストを出力)を行います。

コンテキストマネージャとは

コンテキストマネージャは、リソースの確保と解放、エラーハンドリングなどを効率的に行うためのPythonの特性です。最も一般的な使用例は、ファイル操作での `with open() as f:` 構文です。

基本的なコンテキストマネージャの作成と使用方法

Pythonでコンテキストマネージャを自作する基本的な方法は以下の通りです。

# コンテキストマネージャの定義
class MyContextManager:
    def __enter__(self):
        print("リソース確保")
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print("リソース解放")

# コンテキストマネージャの使用
with MyContextManager() as cm:
    print("何か処理")

この例では、`with` 文を使用してリソースの確保と解放を行っています。

応用例1:タイミング計測デコレータ

関数の処理にかかる時間を計測するデコレータを作成してみましょう。

import time

def timer_decorator(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end - start} seconds")
        return result
    return wrapper

@timer_decorator
def complex_function(num):
    # 何か時間のかかる処理
    for _ in range(num):
        pass

このデコレータは、関数が何秒で終了したかを表示します。

応用例2:自動リトライ機能を持たせたコンテキストマネージャ

通信エラーが発生した場合などに自動でリトライする機能を持たせたコンテキストマネージャを考えます。

import time
class AutoRetryContextManager:
    def __enter__(self):
        print("リトライ準備")
        self.retry_count = 0
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is not None:
            print(f"エラー発生:{exc_value}")
            self.retry_count += 1
            if self.retry_count < 3:
                print("リトライします")
                time.sleep(1)
                return True  # エラーをキャッチしてリトライ
        print("リソース解放")
with AutoRetryContextManager() as cm:
    print("何か処理")
    raise ValueError("何らかのエラー")  # 仮のエラー

このコンテキストマネージャは、エラーが発生した場合に自動でリトライします(最大3回)。

まとめ

Pythonの「デコレータ」と「コンテキストマネージャ」は、コードの再利用性や効率性を高めるための非常に便利な機能です。これらの機能を理解し、適切に活用することで、より高度なプログラミングが可能になります。

コメント

コメントする

目次