闭包函数简介
闭包函数:必须符合下面两个特征才能称为闭包函数
1.定义在函数内部的函数;
2.内部函数使用了外部函数名称空间中的名字;
def func(username): def index(): print(username) return index res = func('aaa') print(res) res() # 打印结果 aaa
装饰器简介
1.装饰器的本质
在不改变被装饰对象原来的‘调用方式’和‘内部代码’的情况下给被装饰对象添加新的功能
2.装饰器的原则
对修改封闭 对扩展开放
from functools import wraps def outer(func_name): @wraps(func_name) def inner(*args, **kwargs): print('执行被装饰对象之前可以做的额外操作') res = func_name(*args, **kwargs) print('执行被装饰对象之后可以做的额外操作') return res return inner
3.知识储备
import time print(time.time()) '''时间戳(秒数):当前距离1970年1月1日0时0分0秒所经历的秒数,可统计代码的运行时间''' time.sleep(2) '''让程序原地等待三秒'''
装饰器的前期推导
import time def index(): time.sleep(3) print('from index') def get_time(): start_time = time.time() # 在调用index函数之前获取一下时间戳 index() # 调用index函数 end_time = time.time() print('函数的执行时间是:',end_time - start_time)
ps:运行上面代码如果要多个不同的函数需要统计时间的话就不够灵活。
import time def index(): time.sleep(3) print('from index') def home(): time.sleep(5) print('from home') def get_time(xxx): start_time = time.time() # 在调用index函数之前获取一下时间戳 xxx(*args,**kwargs) # 调用index函数 end_time = time.time() print('函数的执行时间是:',end_time - start_time) get_time(index) get_time(home)
ps:将代码优化成上述代码后可以实现统计多个不同的函数。
装饰器各种版本
import time """针对有参无参函数如何兼容""" def outer(xxx): def get_time(*args, **kwargs): start_time = time.time() # 在调用index函数之前获取一下时间戳 res = xxx(*args, **kwargs) # 调用index函数 end_time = time.time() print('函数的执行时间是:', end_time - start_time) return res return get_time def index(name): time.sleep(1) print('from index') return '执行index函数之后的返回值' home = outer(home) xxx = home() print(xxx)
ps:上述代码在装饰器中先用一个变量把被装饰的函数返回值确定实现了对参数有误的兼容,完成了一个简易但完整的装饰器。
装饰器的固定模版
1.装饰器固定模版
针对很多人无法快速的领悟和理解装饰器的作用,可以直接记固定模版
from functools import wraps def outer(func_name): @wraps(func_name) # 仅仅是为了让装饰器不容易被别人发现 做到真正的以假乱真 def inner(*args, **kwargs): print('执行被装饰对象之前可以做的额外操作') res = func_name(*args, **kwargs) print('执行被装饰对象之后可以做的额外操作') return res return inner
2.装饰器语法糖
@ 符号就是装饰器的语法糖
import time from functools import wraps def outer(func_name): @wraps(func_name) # 仅仅是为了让装饰器不容易被别人发现 做到真正的以假乱真 def inner(*args, **kwargs): print('执行被装饰对象之前可以做的额外操作') res = func_name(*args, **kwargs) print('执行被装饰对象之后可以做的额外操作') return res return inner @outer # home = outer(真正的函数名home) def home(): '''我是home函数 我要热死了!!!''' time.sleep(1) print('from home') return 'home返回值' help(home) '''home() 我是home函数 我要热死了!!!''' print(home) '''<function home at 0x7ff02a4d9310> 执行被装饰对象之前可以做的额外操作''' home() '''from home 执行被装饰对象之后可以做的额外操作'''
ps:在python中help ()函数用于查看函数或模块用途的详细说明
#### 今日作业###
1.编写一个用户认证装饰器
基本要求
执行每个函数的时候必须先校验身份 eg: jason 123
拔高练习(有点难度)
执行被装饰的函数 只要有一次认证成功 那么后续的校验都通过
函数:register login transfer withdraw
提示:全局变量 记录当前用户是否认证