python使用装饰器实现面向切面编程

一,装饰器的概念与使用

文章见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")

普通人解决方案,显然利用第二种方案,使用装饰器后不仅将代码模块化,而且更能清晰明了的表达代码作用

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")

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值