python装飾器を用いて接面プログラミングを実現

5606 ワード

一、装飾器の概念と使用
文章の見方https://www.jb51.net/article/153214.htm,本文は余計な説明はしない
二、装飾器は切面向けのプログラミングを実現する具体的な方法
周知のように、装飾器はpythonの文法糖であり、コードの書き方を簡略化し、コードの多重化を高める上で大きな意義があり、装飾器はログ、タイマー、ログインチェックによく用いられ、djangoのlogin_requiredはページアクセスを制約し、ログインしてこそページにアクセスでき、装飾器の役割はこれに限らない.
例を挙げます.
現在の所有者の要件は次のとおりです.
djangoビューに時間のかかる操作があると仮定しますが、時間のかかる操作に遭遇すると、クライアントには待機時間があります.これはお客様の体験に大きな影響を与えます.ユーザーは神様と呼ばれています.私たちは偽のデータを作ってフロントに戻り、バックグラウンドのデータがデータを取っていることをフロントに伝えなければなりません.抵抗できないため、カートンが遅延しています.
菜鳥級ソリューション:
各ビューについて、タイムアウト時間を増加すると、タイムアウトはデフォルトの空のjson文字列をフロントに返します.
import json
import time
import signal
from django.http import HttpResponse


def view1():
    try:
        signal.signal(signal.SIGALRM, myHandler)
        signal.alarm(1)  #         
        response = urllib2.urlopen("      A")
        result_str = json.loads(response.read())
        signal.alarm(0)
        return HttpResponse(result_str, content_type="application/json")
    except:
        return HttpResponse({}, content_type="application/json")


def view2():
    try:
        signal.signal(signal.SIGALRM, myHandler)
        signal.alarm(1)  #         
        response = urllib2.urlopen("      B")
        result_str = json.loads(response.read())
        signal.alarm(0)
        return HttpResponse(result_str, content_type="application/json")
    except:
        return HttpResponse({}, content_type="application/json")


def view3():
    try:
        signal.signal(signal.SIGALRM, myHandler)
        signal.alarm(1)  #         
        response = urllib2.urlopen("      C")
        result_str = json.loads(response.read())
        signal.alarm(0)
        return HttpResponse(result_str, content_type="application/json")
    except:
        return HttpResponse({}, content_type="application/json")
    
    
    
    
def view4():
    try:
        signal.signal(signal.SIGALRM, myHandler)
        signal.alarm(1)  #         
        response = urllib2.urlopen("      D")
        result_str = json.loads(response.read())
        signal.alarm(0)
        return HttpResponse(result_str, content_type="application/json")
    except:
        return HttpResponse({}, content_type="application/json")

普通の人の解決策、明らかに第2の方案を利用して、装飾器を使った後にコードをモジュール化するだけではなくて、その上更にはっきりしたコードの作用を表現することができます
def TimeOut(func):
        def function(*args, **kwargs):
            try:
                signal.signal(signal.SIGALRM, myHandler)
                signal.alarm(1)
                stime = time.time()
                print("      ")
                func(*args, **kwargs)
                print("      ")
                print(time.time() - stime)
                signal.alarm(0)
            except:
                return HttpResponse({}, content_type="application/json")
        return function


@TimeOut
def view1():
    response = urllib2.urlopen("      A")
    result_str = json.loads(response.read())
    signal.alarm(0)
    return HttpResponse(result_str, content_type="application/json")


@TimeOut
def view2():
    response = urllib2.urlopen("      B")
    result_str = json.loads(response.read())
    return HttpResponse(result_str, content_type="application/json")


@TimeOut
def view3():
    response = urllib2.urlopen("      C")
    result_str = json.loads(response.read())
    return HttpResponse(result_str, content_type="application/json")


@TimeOut
def view4():
    response = urllib2.urlopen("      D")
    result_str = json.loads(response.read())
    return HttpResponse(result_str, content_type="application/json")

オオカミソリューション:各ビュー関数のカスタマイズに必要な結果を返す
def TimeOut(view):
    def wrap(func):
        def function(*args, **kwargs):
            try:
                signal.signal(signal.SIGALRM, myHandler)
                signal.alarm(1)
                stime = time.time()
                print("      ")
                func(*args, **kwargs)
                print("      ")
                print(time.time() - stime)
                signal.alarm(0)
            except:
                if view == "view1":
                    dict = "view1       "
                if view == "view2":
                    dict = "view2       "
                if view == "view3":
                    dict = "view3       "
                if view == "view4":
                    dict = "view4       "
                return HttpResponse(dict, content_type="application/json")

        return function

    return wrap


@TimeOut("view1")
def view1():
    response = urllib2.urlopen("      A")
    result_str = json.loads(response.read())
    signal.alarm(0)
    return HttpResponse(result_str, content_type="application/json")


@TimeOut("view2")
def view2():
    response = urllib2.urlopen("      B")
    result_str = json.loads(response.read())
    return HttpResponse(result_str, content_type="application/json")


@TimeOut("view3")
def view3():
    response = urllib2.urlopen("      C")
    result_str = json.loads(response.read())
    return HttpResponse(result_str, content_type="application/json")


@TimeOut("view4")
def view4():
    response = urllib2.urlopen("      D")
    result_str = json.loads(response.read())
    return HttpResponse(result_str, content_type="application/json")