Pythonのデコレータは非常に強力で便利なツールです。デコレータは、関数やクラスの振る舞いを変更することができます。具体的には、他の関数をラップして、そのラップされた関数の振る舞いを拡張することができます。
デコレータは、他の関数の機能を変更したり拡張したりすることができる関数です。デコレータ関数を定義し、修正したい関数に @decorator_name という構文を追加します。
def my_decorator(func):
def wrapper():
print("start")
func()
print("end")
return wrapper
@my_decorator
def say_hello():
print("hello")
say_hello()
上記のコードを実行すると、以下の結果が得られます。
start
hello
end
@my_decorator はPythonの糖衣構文です。say_hello関数をmy_decorator関数の引数として渡すことができます。簡単に言うと、 @my_decorator は以下の記述と同じです。
say_hello = my_decorator(say_hello)
つまり、元の関数をデコレータ関数の中に入れて実行することで、元の関数がデコレータの戻り関数に置き換わるのです。say_hello()を呼び出す時、実際には元のsay_hello()ではなく、wrapper()関数を呼び出しているのです。
引数のある例を見てみましょう。
def count_and_sum(func):
def wrapper(*args, **kwargs):
wrapper.count += 1
result = func(*args, **kwargs)
wrapper.sum += result
return result
wrapper.count = 0
wrapper.sum = 0
return wrapper
@count_and_sum
def add(x, y):
return x + y
print(add(1, 2)) # 3
print(add(3, 4)) # 7
print(add(5, 6)) # 11
print("Total count: ", add.count) # 3
print("Total sum: ", add.sum) # 21
@count_and_sum をaddの前に付けると、addがcount_and_sumの引数として渡されます。count_and_sumでは、wrapperがaddを引数に取り、addが呼ばれた回数と合計を計算します。add(x, y)が呼ばれるたびに、実際にはwrapper(x, y)が呼ばれ、addが呼ばれた回数と合計が加算されることになります。count_and_sumはwrapperを返すので、元のaddを統計機能のある関数に変更することができます。add.countとadd.sumはwrapperで定義された変数です。addを @count_and_sum で変更すると、wrapperが実行されるので、wrapper内の変数が生成されてaddに格納され、add.countとadd.sumが値を持つことができるようになります。
以上がPythonのデコレータと引数についての基本的な説明です。この記事がPythonのデコレータと引数の理解に役立つことを願っています。