1.装饰器定义:
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能。
2.装饰器使用:
首先我们需要知道:
- 函数可以当做一个变量
- 函数的参数也可以是函数
- 函数是可以嵌套的
开放封闭原则:
- 封闭:已实现的功能代码尽可能的不要做修改
- 开放:对现有的功能代码可扩展
示例:
需求:遵守开发封闭的原则,在调用f1()/f2()函数时,先打印出《python自动化测试实战》这句话,再输出f1或f2的值
def getInfo(func): def inner(): print('《python自动化测试实战》') func() return inner @getInfo #装饰器 def f1(): #被装饰的函数,就是装饰器的参数 print('网易云课堂') def f2(): print('51CTO平台')
f1()
#代码执行顺序:
1.执行调用f1()
2.先执行getInfo函数,找到inner函数,输出: 《python自动化测试实战》
3.再执行func()函数,实际上就是func=f1(),输出: 网易云课堂
四个步骤:
1.执行getInfo函数的时候,把被装饰的函数f1当做参数来传递
2.getInfo函数的返回值会出现赋值
3.一旦结合了装饰器后,调用f1的函数其实执行的是inner函数的内部,原来的函数f1被覆盖
4.被装饰的函数f1出现赋值给装饰器的内层函数inner
3.登录案例
def login(func): #func=frofile def inner(token='krjgefj'): if token=='krjgefj': return func(token) else: return '请登录系统' return inner @login def profile(token): #带了参数 return '你的主页信息' print(profile('krjgefj'))
#代码执行顺序
1.在调用profile()函数之前先执行login函数
2.判断参数是否等于krjgefj,等于的话就直接执行func(token)函数,即profile(token)
针对带不定参数的装饰器写法:
def outer(func):
def inner(*args,**kwargs):
print(args,kwargs)
func()
return inner
4.实战
需求:要求注册账户,然后注册的账户登录到系统后,显示出登录的昵称
1.注册的函数
2.登录的函数
3.登录后获取昵称的函数
传统写法:重复代码较多
def register(): '''实现账户的注册功能''' username=input('请输入账号: ') password=input('请输入密码: ') '''把获取到账户信息写入当前目录的文件login.md''' temp=username+'|'+password #用|进行分割 with open('login.md','w') as f: f.write(temp) def login(): '''实现登录功能''' username=input('请输入账号: ') password=input('请输入密码: ') '''读取login.md的内容''' with open('login.md','r') as f: info=f.read() info=info.split('|') #用|进行分割 if username==info[0] and password==info[1]: return True else: return False def getnick(func): '''获取昵称''' with open('login.md','r') as f: info=f.read() info=info.split('|') #用|进行分割 if func: print('{0}您好,欢迎你访问无涯课堂'.format(info[0])) else: print('请登录系统')
if __name__ == '__main__': while true: t = int(input('1.注册 2.登录 3.退出系统 ')) if t==1: register() elif t==2: getnick(login()) elif t==3: import sys sys.exit(1) #退出 else: print('输入错误,请继续...') contunie
修改后,把重复代码提出来的写法:
def inOut(): username=input('请输入账号: ') password=input('请输入密码: ') return username,password def register(): '''实现账户的注册功能''' username,password=inOut() '''把获取到账户信息写入当前目录的文件login.md''' temp=username+'|'+password #用|进行分割 with open('login.md','w') as f: f.write(temp) def login(): '''实现登录功能''' username,password=inOut() '''读取login.md的内容''' with open('login.md','r') as f: info=f.read() info=info.split('|') #用|进行分割 if username==info[0] and password==info[1]: return True else: return False def getnick(func): '''获取昵称''' with open('login.md','r') as f: info=f.read() info=info.split('|') #用|进行分割 if func: print('{0}您好,欢迎你访问无涯课堂'.format(info[0])) else: print('请登录系统') if __name__ == '__main__': while true: t = int(input('1.注册 2.登录 3.退出系统 ')) if t==1: register() elif t==2: getnick(login()) elif t==3: import sys sys.exit(1) #退出 else: print('输入错误,请继续...') contunie