#はじめに
デコレーターとは何なのか、それを説明する前に、一つ簡単な問題を解決してみよう
問題1
def print_str():
print("hello world")
print_str関数が存在します、"hello world"を出力すると同時に、現在時間も出力してみましょう
# 時間モジュールをインポート
from datetime import datetime
def print_str():
print("hello world")
print(datetime.now())
print_str()
#出力結果
hello world
2019-06-15 00:09:09.878962
関数内部に時間を出力するcodeを追加すれば、簡単に出来ます
では、問題を少し変えてみましょう
問題2
print_str関数が存在します、"hello world"を出力する同時に現在時間も出力してみましょう。
ただし、関数内部で時間出力のcodeを追加してはならない
from datetime import datetime
def decorator(func):
def wrapper():
print(datetime.now())
func()
return wrapper
def print_str():
print("hello world")
f = decorator(print_str)
f()
#出力結果
2019-06-15 09:28:45.585808
hello world
###デコレーターの定義
ここで定義された関数decorator
がデコレーターです。
問題を踏まえて、デコレーターの定義を説明すると、
関数の内部を変換せず、新しい機能を動的に追加することを可能にします。
###略式呼び出し方
@マーク+関数名でデコレーターを関数に簡単に装着も可能
def decorator(func):
def wrapper():
print(datetime.now())
func()
return wrapper
# @マーク+関数名でデコレーターを関数に簡単に装着も可能
@decorator
def print_str():
print("hello world")
print_str()
# 出力
2019-06-15 09:39:06.419550
hello world
###複数パラメータ存在する関数の対応方法
from datetime import datetime
def decorator(func):
# 可変長引数をデコレーターにあたえ
def wrapper(*args, **kw):
print(datetime.now())
func(*args, **kw)
return wrapper
@decorator
def print_str(name, **kw):
print("hello world" + name)
print(kw)
print_str(" byby",a=1,b=2)
#出力
2019-06-15 10:00:03.465790
hello world byby
{'a': 1, 'b': 2}
flaskについて簡単に紹介します。
pythonのウェブフレームワーク、現時点(2019/06/15)、githubでのstarsの数は44734、Djangoのstarsの42174よりも多いですよ
flaskでのデコレーターの使用例を見てみましょう、flaskが分からなくても大丈夫です、説明入ります
@api.route('/get', methods=['GET'])
def test_get_rout():
name = request.args.get('name')
return name, 200
# Djangoの場合はrouteファイル存在しますが
# flaskではデコレーターでルーティングを実現してます
@api.route('/psw',methods=['GET'])
@auth.login_required
def get_psw():
psw = request.args.get('psw')
return 'ok', 200
# 一つの関数に対して複数のデコレーターをつけることも可能
# @auth.login_requiredはこのrouteのアクセス権限を決めてます
flaskのルーティングのデコレータは、大量なコードによって実現されている。
もしそれを関数内で定義すると、一つの関数の中身は膨大に膨らみ、読み難いcodeになります、デコレータ使用することで、それを上手く回避できた、良いデコレータの実用例だと思います
Simple is better than complex.
複雑であるよりは平易であるほうがいい。--pythonの哲学