python 带参与不带参装饰器的使用与流程分析

一.什么是装饰器

装饰器是用来给函数动态的添加功能的一种技术,属于一种语法糖。通俗一点讲就是:在不会影响原有函数的功能基础上,在原有函数的执行过程中额外的添加上另外一段处理逻辑

二.装饰器功能实现的技术基础--闭包

什么是闭包?闭包就是:一个内部函数被一个外部函数当做返回值进行返回,并且内部函数引用了外部函数提供的变量, 此时将内部函数和引用的外部变量构成的整体称为闭包

闭包的特征?闭包有一个明显的特征就是:引用了外部变量的闭包能够让外部函数不被释放,如果外部函数被释放,就会导致内部函数访问变量时出错

闭包中内部函数如何修改外部函数提供的变量? python3 如果要在闭包内修改外部函数提供的变量,需要使用(nonlocal 变量名称)  进行声明变量不是本地变量,才能进行更改 , python2 中,需要在闭包外先将变量添加到一个列表里,再在闭包内通过下标取出变量,然后进行更改使用。

三.装饰器的使用场景

  引入日志
  函数执行时间统计
  执行函数前预备处理
  执行函数后清理功能
  权限校验等场景
  缓存

三.不带参的装饰器的使用与流程分析

装饰阶段:调用外层函数 (在调用被装饰函数前,已经经历装饰阶段)
运行阶段:调用内层函数和  内层函数的函数体中的func指向的 装饰器下的函数 (运行阶段就是调用被装饰函数的时候)
#coding=utf-8

from django.shortcuts import redirect
from django.http import HttpResponseRedirect
from rest_framework.response import Response


def login(func): # 登录验证装饰器,如果未登录就转到登录页面
    def login_func(request, *args, **kwargs)
        if user_id in request.session
            return func(request, *args, **kwargs)
        else:
            返回还是一个response对象,可以用来设置cookie,session等
            redi = HttpResponseRedirect('./user/login')
            # 设置cookie,当用户尚未登录时就进行需要登录后才能进行的操作,
            # 就先记住用户的当前所处的页面,登录时,通过取回cookie则将用户登录前所处的页面返回
            redi.set_cookies('url', request.get_full_path())
            return redi
    return login_func # 返回时使用了变量名称 api_list 进行接收


@login
def api_list(request): 
    return Response(status=status.HTTP_200_OK)

api_list(request) # 假设存在这么一个调用逻辑。当然了,在实际的接口,并不是我们开发人员手动去调用的,有用户请求了才会触发。
# request.get_full_path() 获取带参数的当前请求所在的页面的url # request.path 获取去掉参数的当前请求所在的页面的url

流程说明:
  1.装饰阶段
  首先,会存在这么一个执行流程(这是解释器去进行的):
  api_list = login(api_list),
  将被装饰的函数的引用进行传参,调用装饰器的外层函数,返回内层函数的引用, 返回值使用了被装饰函数的函数名称进行接收,此时的状态就是:
  api_list 指向了 原来 login_func 包含的函数体,func 指向了 原来api_list所指向的函数体,注意是 原来!
  2.运行阶段
    当使用 ret = api_list(request) 进行函数的调用时,因为 api_list 已经指向了 原来 login_func 所包含的函数体,也就是装饰器的内层
    函数。所以,装饰器的内层函数开始执行,func被调用,因为此时 func 指向了原来 api_list 所包含的函数体,最后,被装饰函数得到执行

注意:外层函数和内层函数也同样要接收 被装饰函数所接收了的参数

四.带参的装饰器的使用与流程分析。。。有空再写

猜你喜欢

转载自www.cnblogs.com/lowmanisbusy/p/10089909.html