一、装饰器:
本质就是函数,功能:为其他函数添加附加功能
原则:
1.不能修改被装饰函数的源代码
2.不能修改被修饰函数的调用方式
一个简单的装饰器
import time def timmer(func): def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) stop_time = time.time() print('函数运行的时间%s'%(stop_time - start_time)) return res return wrapper @timmer def cal(l): res = 0 for i in l: time.sleep(0.01) res += i return res ret = cal(range(200)) print(ret)
二、装饰器的知识储备
装饰器 = 高阶函数 + 函数嵌套 + 闭包
高阶函数定义:
1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名
3.满足上述条件任意一个,都可称之为高阶函数
用高阶函数模拟装饰器:
结果多运行了一次
import time def foo(): time.sleep(3) print('来自foo') def timmer(func): start_time = time.time() func() stop_time = time.time() print('函数运行的时间是%s' %(stop_time - start_time)) return func foo = timmer(foo) foo()
三、 函数嵌套及闭包
嵌套就是,函数里再定义函数
闭包:闭----->封装的变量 包----->一层层函数
每个包找变量先从自身那层开始找,找不到再从外层找
重点:函数即变量
def father(name): def son(): print('我的爸爸是%s' %name) def grandson(): name = 'China' print('我的爷爷是%s' %name) grandson() son() father('河南')
装饰器框架
def timmer(func): def wrapper(): #增加功能 func() return wrapper
补充该装饰器架子
import time def timmer(func): def wrapper(): #增加功能 start_time = time.time() func() stop_time = time.time() print('运行时间是%s'%(stop_time - start_time)) return wrapper def test(): time.sleep(2) print('test函数运行完毕') res = timmer(test) #返回的是wrapper的地址 res() #执行的是wrapper()
可以看出,只要把函数的最后两行代码的函数接收值改为:test
即:
test= timmer(test) test()
看起来符合装饰器原则
但每次给函数增加功能都得写一遍 test= timmer(test),显然不合理
所以,用@timmer 去代替test = timmer(test)
import time def timmer(func): def wrapper(): #增加功能 start_time = time.time() func() stop_time = time.time() print('运行时间是%s'%(stop_time - start_time)) return wrapper @timmer #就相当于:test = timmer(test) def test(): time.sleep(2) print('test函数运行完毕') test()
四、加上返回值的装饰器
import time def timmer(func): def wrapper(): #增加功能 start_time = time.time() res = func() #这里执行的函数test,所以要在这里给函数一个接收返回值的变量 stop_time = time.time() print('运行时间是%s'%(stop_time - start_time)) return res #这里要返回test的返回值 return wrapper @timmer #就相当于:test = timmer(test) def test(): time.sleep(2) print('test函数运行完毕') return '这是test的返回值' a = test() print(a)
五、加上参数的装饰器
import time def timmer(func): def wrapper(*args, **kwargs): #可接受任意值 #增加功能 start_time = time.time() res = func(*args, **kwargs) #将wrapper接受的值原封传给func stop_time = time.time() print('运行时间是%s'%(stop_time - start_time)) return res return wrapper @timmer #就相当于:test = timmer(test) def test1(name, age, gander): time.sleep(2) print('test1运行结果名字为%s年龄为%d性别为%s'%(name, age, gander)) return '这是test1的返回值' a = test1('jinling', 20, 'female') print(a) @timmer def test2(name, age): time.sleep(3) print('test2函数运行结果名字为%s年龄为%d'%(name, age)) return '这是test2的返回值' b = test2('liuwen', 18) print(b)
六、实现一个验证功能装饰器
def func_ver(func): def wrapper(*args, **kwargs): name1 = input('请输入用户名:') pd = input('请输入用户密码:') if name1 == 'PJL' and pd == '123': func(*args, **kwargs) else: print('用户名或密码错误') return wrapper @func_ver def index(): print('欢迎来到的我的网站') @func_ver def home(name): print('%s欢迎回家'%name) @func_ver def secrect(name): print('%s这是你的小秘密'%name) index() home('jinling') secrect('jining')