Python中的-装饰器

6次阅读

共计 2376 个字符,预计需要花费 6 分钟才能阅读完成。

在阐述什么是装饰器前,我们先来说一下什么是闭包

闭包:

在一个外函数中 定义了一个内函数

内函数运用了 外函数的临时变量

外函数的返回值 是内函数的引用

def outer():

a=100

def inner():

b=a+100

print(b)

return inner

outer()()

装饰器:

以 @开头,装饰器是在函数调用之上的修饰器,在不改变项目原有代码的基础上,增加一些额外的功能

装饰器使用场景

授权:装饰器能有助于检查某个人是否被授权去使用一个 web 应用的端点 (endpoint)。它们被大量使用于 Flask 和 Django web 框架中

日志:在记录日志的地方添加装饰器

缓存:通过装饰器获取缓存中的值

函数装饰器

一个装饰器:

def outer(func):

def inner(a,b) / def inner(*args,**kwargs):

print(“ 特殊效验功能的执行 ”)

func(a,b) / func(*args,**kwargs)

print(“ 停止执行 ”)

return inner

@outer

def f(a,b):

print(“a+b=”,(a+b))

f(10,20)

# 输出结果:

特殊效验功能的执行

30

停止执行

多个装饰器:

开始:自上而下

结束:自下而上

def outer1(func):

def inner(a,b) / def inner(*args,**kwargs):

print(“ 特殊效验功能 1 的执行 ”)

print(“111111111111”)

func(a,b) / func(*args,**kwargs)

print(“1 停止执行 ”)

print(“111111111111”)

return inner

def outer2(func):

def inner(a,b) / def inner(*args,**kwargs):

print(“ 特殊效验功能 2 的执行 ”)

print(“222222222222”)

func(a,b) / func(*args,**kwargs)

print(“2 停止执行 ”)

print(“222222222222”)

return inner

@outer1

@outer2

def f(a,b):

print(“a+b=”,(a+b))

f(10,20)

输出结果:特殊功能效验 1 的执行

111111111111

特殊功能效验 2 的执行

222222222222

30

2 停止执行

222222222222

1 停止执行

111111111111

类装饰器的运用

这里的代码,展示的是 jwt 和 类装饰的结合使用

目的:防止用户 使用他人敏感信息 进行篡改

import jwt

装饰器

def my_decorator(func):

def wrapper(request,*args,**kwargs):

print(‘ 这个装饰器被调用了 ’)

print(‘ 请求接口地址是 %s’ % request.path)

判断 jwt 逻辑

uid = request.GET.get(“uid”)

clinet_jwt = request.GET.get(“jwt”,None)

if clinet_jwt is None:

return HttpResponse(‘ 没有令牌 ’)

decode_jwt = jwt.decode(clinet_jwt,’123′,algorithms=[‘HS256’])

if decode_jwt[‘uid’] != str(uid):

return HttpResponse(‘ 你篡改了用户 id’)

return func(request,*args,**kwargs)

return wrapper

类装饰器调用

from django.utils.decorators import method_decorator

在查询用户信息类时 调用

用户信息

class UserInfo(APIView):

@method_decorator(my_decorator)

def get(self,request):

uid = request.GET.get(‘uid’)

查询数据

user = User.objects.get(id=int(uid))

序列化对象

user_ser = UserSer(user)

return Response(user_ser.data)

在 用户登录接口 后端

登录接口

class Login(APIView):

def get(self,request):

接收参数

username = request.GET.get(‘username’,’ 没有接受到 ’)

password = request.GET.get(‘password’,’ 没有接受到 ’)

查询数据

user = User.objects.filter(username=username,password=make_password(password)).first()

if user:

res = {}

res[‘code’] = 200

res[‘message’] = ‘ 登录成功 ’

res[‘username’] = user.username

res[‘uid’] = user.id

加入 jwt 编码机制

进行编码

智汇代理申请 http://www.kaifx.cn/broker/th…

encode_jwt = jwt.encode({‘uid’:str(user.id)},’123′,algorithm=’HS256′)

解码操作

强转

encode_str = encode_jwt.decode(‘utf-8’)

res[‘jwt’] = encode_str

return Response(res)

else:

res = {}

res[‘code’] = 405

res[‘message’] = ‘ 用户名或密码错误 ’

return Response(res)

在前端的登录 接口中 要将 jwt 存储到 localStorage 里面

localStorage.setItem(‘jwt’,result.data.jwt)

正文完
 0