本文共 3976 字,大约阅读时间需要 13 分钟。
import timedef decorate(func): def wrapper(): print('正在校验') time.sleep(2) print('校验完成') #调用原函数 func() return wrapper@decoratedef f1(): print('---f1---')def f2(): print('---f2---')f1()f2()'''正在校验校验完成---f1------f2---'''
被装饰的函数f1作为参数传给func,加载wrapper函数然后扔给f1,加载完成,f1()进行调用
此处只装饰了f1,顾有2s时延,而调用f2没有实验直接打印
import timedef decorate(func): def wrapper(): print('正在校验') time.sleep(2) print('校验完成') #调用原函数 func() return wrapper@decoratedef f1(n): print('---f1---',n)f1(5) #此时f1是wrapper,wrapper没有参数,但f1又需要参数。矛盾'''TypeError: wrapper() takes 0 positional arguments but 1 was given'''
解决办法:wrapper加x参数,func加x
import timedef decorate(func): def wrapper(x): print('正在校验') time.sleep(2) print('校验完成') #调用原函数 func(x) return wrapper@decoratedef f1(n): print('---f1---',n)@decoratedef f2(name): print('---f2---',name)@decorate #校验步骤def f3(students): #列表 for stu in students: print(stu)f1(5)f2('steven')students=['steven','william','july']f3(students)
传两个参数怎么办?-->怎么构建万能装饰器
import timedef decorate(func): def wrapper(*x): print('正在校验') time.sleep(2) print('校验完成') #调用原函数 func(*x) return wrapper@decoratedef f1(name,age): print('---f1---',name,age)f1('lily',1)
加入关键字参数
import timedef decorate(func): def wrapper(*x): print('正在校验') time.sleep(2) print('校验完成') #调用原函数 func(*x) return wrapper@decorate # 校验步骤def f3(students,class_='1905'): # 列表 for stu in students: print(stu)students = ['steven', 'william', 'july']f3(students,class_='1904')'''TypeError: wrapper() got an unexpected keyword argument 'class_''''
解决办法 *x--->*x,**kwargs 变为万能装饰器
import timedef decorate(func): def wrapper(*x,**kwargs): print('正在校验') time.sleep(2) print('校验完成') #调用原函数 func(*x,**kwargs) return wrapper@decorate # 校验步骤def f3(students,class_='1905'): # 列表 print('{}班的学生如下:'.format(class_)) for stu in students: print(stu)students = ['steven', 'william', 'july']f3(students,class_='1904')'''正在校验校验完成1904班的学生如下:stevenwilliamjuly'''
class参数不传也可以,因为有默认值
装饰器能不能装两层? --->能
def zhuang1(func): print('--->1 start') def wrapper(*x,**xx): func() print('刷漆') print('--->1 end') return wrapperdef zhuang2(func): print('--->2 start') def wrapper(*x, **xx): func() print('铺地板装门') print('--->2 end') return wrapper@zhuang2@zhuang1 #离的近的先装def house(): print('我是毛坯房')house()'''--->1 start--->1 end--->2 start--->2 end我是毛坯房刷漆铺地板装门'''
如果装饰器是多层的,谁距离函数最近优先使用该装饰器
函数和套娃1作为整体扔到套娃2中
带参数装饰器 装三层函数
最外层的函数负责接收装饰器参数
里面的内容还是装饰器的内容
def outer(a): #第一层,负责接收装饰器参数 def decorate(func): #第二层,负责接收函数 def wrapper(*x,**xx): #第三层,负责接收函数实参 func(*x,**xx) print('铺地砖{}块'.format(a)) return wrapper #返出第三层函数 return decorate #返出第二层函数@outer(a=10)def house(time): #函数带参数 print('我{}拿到房子,是毛坯房'.format(time))@outer(a=100)def street(): print('新修街道:黑泉路')house('2021.04.26')street()'''我2021.04.26拿到房子,是毛坯房铺地砖10块新修街道:黑泉路铺地砖100块'''
练习
'''定义装饰器进行付款验证结构:def login_required(): def wrapper(*args,**kwargs): 验证用户是否登录 return wrapper'''#定义一个登录函数def login(): username=input('输入用户名:') password=input('输入密码:') if username=='admin' and password=='123': return True else: return False#定义一个装饰器,进行付款验证def login_required(func): def wrapper(*args,**kwargs): global islogin print('---付款---') if islogin: func(*args,**kwargs) else: #跳转到登陆页面 print('用户未登录,不能付款') islogin = login() print('result:',islogin) return wrapper@login_requireddef pay(money): print('正在付款,金额:{}元'.format(money)) print('付款中') time.sleep(2) #模拟付款输密码过程 print('付款成功!')#调用pay(100)pay(200)'''---付款---用户未登录,不能付款输入用户名:admin输入密码:123result: True---付款---正在付款,金额:200元付款中付款成功!'''
转载地址:http://tzegn.baihongyu.com/