Pythonにおいて、デコレータは非常に強力な機能であり、クラスの拡張にも役立つ道具です。この記事では、デコレータを用いたクラスの拡張に焦点を当てます。具体的なコード例とその解説、さらには応用例を含めてご紹介します。
目次
デコレータとは
デコレータは、Pythonでよく用いられるプログラムの構造要素の一つです。関数やメソッド、クラスを修飾して新しい振る舞いを追加するためのものです。
基本的なデコレータの使い方
最も一般的なデコレータの使い方は、関数に対してです。ここではその基本形を確認します。
# 基本的なデコレータの例
def my_decorator(func):
def wrapper():
print("何か前処理")
func()
print("何か後処理")
return wrapper
@my_decorator
def say_hello():
print("こんにちは")
say_hello() # 出力: 何か前処理 こんにちは 何か後処理
クラスにデコレータを適用する
クラスに対するデコレータは、そのクラス全体の振る舞いを一度に変更できる点で非常に便利です。
クラスのメソッドにデコレータを適用
クラスの各メソッドにデコレータを適用する例を見てみましょう。
# メソッドにデコレータを適用
def method_decorator(method):
def wrapper(self):
print(f"{self.name}は動き始めた")
method(self)
print(f"{self.name}は動き終わった")
return wrapper
class MyClass:
def __init__(self, name):
self.name = name
@method_decorator
def method_one(self):
print(f"{self.name}はmethod_oneを実行中")
obj = MyClass("John")
obj.method_one()
# 出力: Johnは動き始めた Johnはmethod_oneを実行中 Johnは動き終わった
応用例
ここでは、デコレータを使ったクラスの拡張の応用例をいくつか紹介します。
ログ出力
クラスのメソッドが呼ばれた際に、ログを出力するデコレータを作成します。
import datetime
# ログ出力用デコレータ
def log_decorator(method):
def wrapper(self):
print(f"{datetime.datetime.now()}: {self.name}が{method.__name__}を実行")
method(self)
return wrapper
class LogClass:
def __init__(self, name):
self.name = name
@log_decorator
def log_method(self):
print("このメソッドはログを取ります")
obj = LogClass("ログ太郎")
obj.log_method()
メソッドの実行時間測定
メソッドの実行にかかる時間を測定するデコレータの例です。
import time
# 実行時間測定デコレータ
def timer_decorator(method):
def wrapper(self):
start = time.time()
method(self)
end = time.time()
print(f"{method.__name__}の実行時間:{end - start}秒")
return wrapper
class TimeClass:
def __init__(self, name):
self.name = name
@timer_decorator
def time_method(self):
for i in range(1000000):
pass
obj = TimeClass("時間太郎")
obj.time_method()
アクセス制限
特定の条件下でのみメソッドの実行を許可するデコレータです。
# アクセス制限デコレータ
def access_control_decorator(method):
def wrapper(self):
if self.allowed:
method(self)
else:
print(f"アクセスが拒否されました")
return wrapper
class AccessClass:
def __init__(self, name, allowed):
self.name = name
self.allowed = allowed
@access_control_decorator
def secure_method(self):
print(f"{self.name}は安全なメソッドを実行")
# テスト
obj1 = AccessClass("許可太郎", True)
obj1.secure_method()
obj2 = AccessClass("拒否太郎", False)
obj2.secure_method()
コメント