装饰器
什么是装饰器:
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能。
语法:@
1.装饰器的原型
def printInfo():
print("我是一个普通的函数")
printInfo()
如何在不允许修改printInfo函数的前提下,在执行printInfo函数前进行权限校验;执行后进行日志记录。
def check(func):
def checkAndLog():
print("函数执行前:权限校验")
func()
print("函数执行后:日志记录")
return checkAndLog #返回内部函数
def printInfo():
print("我是一个普通的函数")
# printInfo()
newFunc = check(printInfo)
newFunc() #执行内部函数
2.装饰器的定义和调用
#装饰器函数定义
def check(func):
def checkAndLog():
print("函数执行前:权限校验")
func()
print("函数执行后:日志记录")
return checkAndLog #返回内部函数(包装过的函数)
@check #定义装饰器修饰的位置,用来修饰谁,相当于check(printInfo)
def printInfo():
print("我是一个普通的函数")
printInfo()#执行函数前,会先执行装饰器
3.装饰器的嵌套
def zs1(func):
def f():
print("我是装饰器1,我来啦")
func()
print("我是装饰器1,我走啦")
return f
def zs2(func):
def f():
print("我是装饰器2,我来啦")
func()
print("我是装饰器2,我走啦")
return f
@zs2
@zs1 #自下而上逐步修饰,zs2会把zs1返回的函数进行修饰,一层套一层
def printInfo():
print("我是一个普通的函数")
printInfo()
4.带参数的装饰器
如果原函数带有参数,那么返回的包装后的新函数也要带有参数,且参数需要一一对应
def tool(func):
def log(name,pwd): #如果log不传入参数,func将接收不到参数
print(f"日志记录【{name}:{pwd}】")
func(name,pwd)
return log #返回包装过的函数
@tool
def login(name,pwd):
print(f"用户名:{name},密码:{pwd}")
login("admin",123456)
5.带返回值的装饰器
返回值和原函数定义时相同
def tool(func):
def log(name,pwd): #如果log不传入参数,func将接收不到参数
print(f"日志记录【{name}:{pwd}】")
state = func(name,pwd)
return state
return log #返回包装过的函数
@tool
def login(name,pwd):
print(f"用户名:{name},密码:{pwd}")
if name == "admin" and pwd == 123456:
return "登陆成功"
return "登录失败"
res = login("admin",123456)
print(res)
6.定义通用的装饰器
增加装饰器的适用性
def tool(func):
def log(*args,**kwargs): #通过使用可变参数来增加装饰器的适用性
print("日志记录前。。。")
state = func(*args,**kwargs)
print("日志记录后。。。")
return state
return log #返回包装过的函数
@tool
def test():
print("我是一个测试函数")
@tool
def login(name,pwd):
print(f"用户名:{name},密码:{pwd}")
if name == "admin" and pwd == 123456:
return "登陆成功"
return "登录失败"
res = login("admin",123456)
print(res)
test()