CodeGym /コース /Python SELF JA /デコレーターの力

デコレーターの力

Python SELF JA
レベル 14 , レッスン 2
使用可能

6.1 クラスメソッドのためのデコレーター

デコレーターはクラスメソッドにも使えるんだ。大事なのは、クラスメソッド用に selfclsという引数を正しく渡すことだね。

クラスの動作についてはまだ勉強していないけど、デコレーターにはこんな機能もあるって知っておいてほしいな。


def log_method_call(func):
    def wrapper(self, *args, **kwargs):
        print(f"メソッド {func.__name__} の呼び出し")
        return func(self, *args, **kwargs)

    return wrapper
        
class MyClass:
    @log_method_call
    def say_hello(self):
        print("Hello from MyClass!")
        
obj = MyClass()
obj.say_hello()

説明

デコレーター (log_method_call): このデコレーターはメソッド funcを受け取って、メソッドの呼び出し前にメッセージを出力する新しい関数wrapperを返すんだ。

デコレーター付きクラスメソッド (say_hello): メソッドsay_helloはデコレーターlog_method_callでラップされて、呼び出し時の追加の動作をするんだ。

出力:


メソッド say_hello の呼び出し
Hello from MyClass!

6.2 複数のデコレーター

1つの関数に複数のデコレーターを重ねて使うことができるよ。デコレーターは宣言された順とは逆の順序で適用されるんだ。


def decorator1(func):
    def wrapper():
        print("デコレーター 1")
        func()

    return wrapper
        
def decorator2(func):
    def wrapper():
        print("デコレーター 2")
        func()

    return wrapper
        
@decorator1
@decorator2
def say_hello():
    print("Hello!")
        
say_hello()

説明

デコレーター (decorator1 と decorator2): これらのデコレーターは関数funcの呼び出し前にメッセージを追加するんだ。

デコレーター付き関数 (say_hello): 関数say_helloは両方のデコレーターでラップされているよ。最初にdecorator2が適用されて、その後にdecorator1が適用されるんだ。

出力:


# デコレーター 1
# デコレーター 2
Hello!

6.3 組み込みデコレーター

Pythonには、静的メソッド、クラスメソッド、プロパティなどの標準的なタスクのためのいくつかの組み込みデコレーターがあるよ。

@staticmethod

@staticmethodデコレーターは、クラスのインスタンスを必要とせずに呼び出せる静的メソッドを作成するために使われるんだ。


class MyClass:
    @staticmethod
    def static_method():
        print("これは静的メソッドです。")
        
MyClass.static_method()

@classmethod

@classmethodデコレーターは、クラス(インスタンスではなく)を最初の引数として受け取るクラスメソッドを作成するために使われるんだ。


class MyClass:
    @classmethod
    def class_method(cls):
        print(f"これはクラスメソッド {cls.__name__} です。")
        
MyClass.class_method()

@property

@propertyデコレーターは、属性のゲッター、セッター、デリーターを作成するために使われるんだ。


class MyClass:
    def __init__(self, value):
        self.hidden_value = value
        
    @property
    def value(self):
        return self.hidden_value
        
    @value.setter
    def value(self, new_value):
        self.hidden_value = new_value
        
obj = MyClass(10)
print(obj.value)  # 出力: 10
obj.value = 20
print(obj.value)  # 出力: 20

これらは組み込みデコレーターで、Pythonのインタプリタがその正しい動作を保証しているんだ。

6.4 デコレーターの使用例

ログ

デコレーターは、関数やメソッドの呼び出しをログに記録するために使われることがあるよ。


def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"関数 {func.__name__} の呼び出し 引数 {args} と {kwargs}")
        return func(*args, **kwargs)

    return wrapper
        
@log_call
def add(x, y):
    return x + y
        
print(add(2, 3))

アクセス制御

デコレーターは、関数やメソッドへのアクセス制御のために使われることがあるよ。


def require_authentication(func):
    def wrapper(*args, **kwargs):
        if not args[0].is_authenticated:
            raise PermissionError("ユーザーが認証されていません。")
        return func(*args, **kwargs)
        
    return wrapper
        
class User:
    def __init__(self, is_authenticated):
        self.is_authenticated = is_authenticated
        
    @require_authentication
    def view_profile(self):
        print("ユーザープロファイル")
        
user = User(is_authenticated=True)
user.view_profile()  # 成功した呼び出し
        
user2 = User(is_authenticated=False)
user2.view_profile()  # PermissionError: ユーザーが認証されていません。

キャッシュ

デコレーターは、関数の結果をキャッシュするために使われることがあるよ。


def cache(func):
    cached_results = {}

    def wrapper(*args):
        if args in cached_results:
            return cached_results[args]
        result = func(*args)
        cached_results[args] = result
        return result

    return wrapper

@cache
def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(35))
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION