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('请输入账号:\n')
password=input('请输入密码:\n')
'''把获取到账户信息写入当前目录的文件login.md'''
temp=username+'|'+password #用|进行分割
with open('login.md','w') as f:
f.write(temp)
def login():
'''实现登录功能'''
username=input('请输入账号:\n')
password=input('请输入密码:\n')
'''读取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.退出系统\n'))
if t==1:
register()
elif t==2:
getnick(login())
elif t==3:
import sys
sys.exit(1) #退出
else:
print('输入错误,请继续...')
contunie
修改后,把重复代码提出来的写法:
def inOut():
username=input('请输入账号:\n')
password=input('请输入密码:\n')
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.退出系统\n'))
if t==1:
register()
elif t==2:
getnick(login())
elif t==3:
import sys
sys.exit(1) #退出
else:
print('输入错误,请继续...')
contunie