デコレータ(decorator)ってなに?
Pythonのデコレータは、関数やメソッドの振る舞いを変更、または強化するための高度な関数機能です。
デコレータを使用すると、関数のソースコードを変更せずに、関数に追加の機能を追加できます。
個人的な理解から言うと、デコレータは関数を別の関数(デコレータ)のパラメータとして渡し、関数に対して何らかの操作を行う方法です。特定の同じ機能を多くの関数に対して実装したい場合、デコレータを定義すると、その関数を呼び出すだけでデコレータの機能も一緒に呼び出されます。非常に便利です。
例
以下は、Pythonのデコレータの書き方と使用方法を示す単純な例です。
# デコレータ関数を定義
def my_decorator(func):
def wrapper():
print("関数を実行する前に、実行するもの。")
func()
print("関数を実行した後に、実行するもの。")
return wrapper
# デコレータを使用して関数をデコレート
@my_decorator
def say_hello():
print("hello, world!")
# デコレートされた関数を呼び出す
say_hello()
このコードでは、my_decorator
というデコレータ関数が定義され、それを使用して say_hello
関数をデコレートしています。say_hello
関数を呼び出すと、デコレータが追加の機能を提供し、結果が表示されます。
関数を実行する前に、実行するもの。
Hello, World!
関数を実行した後に、実行するもの。
バグ
今日私の練習で発生したバグはこちらです。
# デコレータ関数を定義
def my_decorator(func):
print("関数を実行する前に、実行するもの。")
func()
print("関数を実行した後に、実行するもの。")
# デコレータを使用して関数をデコレート
@my_decorator
def say_hello():
print("hello, world!")
# デコレートされた関数を呼び出す
say_hello()
要するに、私は呼び出したい関数をデコレータの内部でラップすることを忘れてしまいました。その結果、エラーが発生しました。
Traceback (most recent call last):
File "c:\Users\sherr\Desktop\RomanWeb\Flask_intro\decorator_fun_practice.py", line 28, in <module>
fast_function()
TypeError: 'NoneType' object is not callable
このエラーは、デコレータを適用すると、デコレータが即座に関数を呼び出すため、say_hello
を明示的に呼び出す前に関数が実行されたとのことです。デコレータが内部でラップされていないため、func()
の呼び出しでエラーが発生します。
まとめ
@my_decorator
が表示されると、呼び出したい関数に対して機能を実装するよってことで、say_hello()を呼び出す前にデコレータ関数が実行されます。
私のバグコードをも一回見たらわかるが、returnしてなく、ただprint実行するので、そのまま実行されちゃうってことです。
簡潔に言えば、@my_decorator
が表示されると、デコレータが関数に適用され、関数を明示的に呼び出す前に実行されることを意味します。内部関数をラップすることにより、デコレータが関数の呼び出しを遅延させることができ、正しい結果が得られます。