一 简介:来学习下装饰器,因为装饰器广泛应用在django框架中
二 前置基础
1 Python 变量作用域的规则是 LEGB
LEGB含义解释:
L —— Local(function);函数内的名字空间
E —— Enclosing function locals;外部嵌套函数的名字空间(例如closure)
G —— Global(module);函数定义所在模块(文件)的名字空间
B —— Builtin(Python);Python内置模块的名字空间
2 闭包函数
内层函数调用外层函数的环境变量
需要注意一点 1必须是外层函数 2是调用环境变量,可以是函数对象和具体变量
代码示例
x=100
def fun()
x=50 #EG
def func() #闭包函数
x=0 #就近L
print(x)
return func #返回闭包函数对象,必须返回
fun()
三 装饰器
一 场景
1 封闭且开放,不要修改装饰器内部的代码,对外开放所有功能
2 当执行完成,才会执行接下来的view函数
3 装饰器本身会返回定义好的函数对象,如果验证通过的话
4 装饰器是典型的闭包函数应用代码
二 语法
@log_required('函数名')
示例代码#session辨别用户是否登录
def examineSession(func):
def wrapper(request, *args, **kwargs):
user = request.session.get("user", None)
if not user: #逻辑判断,简化版if not request.user(如果不存在用户)
return render(request, "admin/login.html")
else:
res = func(request, *args, **kwargs)
return res #需要返回值
return wrapper #返回内置函数本身
index=examineSession(func) index()(这是最原始的调用方法)
@examineSession 语法糖,简写
三 总结
1 编写装饰器的关键是在于提取公共代码进行封装,封装成一个内部函数类似于示例代码的inner()
2 常见的时间统计,登录验证等固定功能
3 是否添加返回值看具体的场景
四 使用django装饰器
1 from django.contrib.auth.decorators import login_required
2 @login_required
系统自带装饰器重定向会有问题,需要进行修改相关参数,(组成?next=下一个目标url)
3 修改 setting login_url配置为='/login'
4 相关问题
1 使用系统自带装饰器需要使用系统自带的登录相关叶敏
2 使用系统自带装饰器需要修改相关url绑定
五 待解决问题
1 ajax与login_required结合的问题
六
类视图中使用装饰器
#定义装饰器
from django.utils.decorators import method_decorator
@method_decorator(my_decorator, name='get')#定义装饰器名称和请求方法
class DemoView(View):
def get(self, request):
print('get方法')
return HttpResponse('ok')
如果需要为类视图的多个方法添加装饰器,但又不是所有的方法(为所有方法添加装饰器参考上面例子),可以直接在需要添加装饰器的方法上使用method_decorator,如下所示
class DemoView(View):
@method_decorator(my_decorator) # 为get方法添加了装饰器
def get(self, request):
print('get方法')
return HttpResponse('ok')
@method_decorator(my_decorator) # 为post方法添加了装饰器
def post(self, request):
print('post方法')
return HttpResponse('ok')
def put(self, request): # 没有为put方法添加装饰器
print('put方法')
return HttpResponse('ok')