10
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

pythonのデコレーターと実用例

Last updated at Posted at 2019-06-15

#はじめに
デコレーターとは何なのか、それを説明する前に、一つ簡単な問題を解決してみよう

問題1

def.py
   def print_str():
       print("hello world")

print_str関数が存在します、"hello world"を出力すると同時に、現在時間も出力してみましょう:point_up_tone1:

print_1.py
   # 時間モジュールをインポート
   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を追加してはならない:point_up:

print_2.py
  
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がデコレーターです。
問題を踏まえて、デコレーターの定義を説明すると、
関数の内部を変換せず、新しい機能を動的に追加することを可能にします。

###略式呼び出し方
@マーク+関数名でデコレーターを関数に簡単に装着も可能

print_3.py
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

###複数パラメータ存在する関数の対応方法

print_4.py
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に置いてのデコレーターの実例
Flask.png

flaskについて簡単に紹介します。
pythonのウェブフレームワーク、現時点(2019/06/15)、githubでのstarsの数は44734、Djangoのstarsの42174よりも多いですよ:point_up:

flaskでのデコレーターの使用例を見てみましょう、flaskが分からなくても大丈夫です、説明入ります

flask.py
@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の哲学

10
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?