1.装饰器的基本概念
功能:不改变现有函数的前提下,扩展函数功能 语法:使用@符号
2.装饰器的原型
问题: 在执行printInfo函数前,进行权限校验;执行后,进行日志记录 不允许修改printInfo函数
def check(func):
def checkAndLog():
print("函数运行前:权限校验...")
func()
print("函数运行后:日志记录...")
return checkAndLog
def printInfo():
print("我是一个普通的函数")
newFunc = check(printInfo)
print("-"*30)
newFunc()
print("-"*30)
printInfo()
print("-"*30)
------------------------------
函数运行前:权限校验...
我是一个普通的函数
函数运行后:日志记录...
------------------------------
我是一个普通的函数
------------------------------
3.装饰器的定义与调用
def check(func):
def checkAndLog():
print("函数运行前:权限校验...")
func()
print("函数运行后:日志记录...")
return checkAndLog
@check
def printInfo():
print("我是一个普通的函数")
printInfo()
函数运行前:权限校验...
我是一个普通的函数
函数运行后:日志记录...
4. 装饰器的嵌套
- 两个及多个装饰器可以装饰同一个函数
- 执行过程为:自下而上逐步修饰,完成后一次性输出
def zsA(func):
def resFunc():
print("zsA执行前...")
func()
print("zsA执行后...")
return resFunc
def zsB(func):
def resFunc():
print("zsB执行前...")
func()
print("zsB执行后...")
return resFunc
print("-"*30)
def test():
print("这是测试函数")
res1 = zsA(test)
res2 = zsB(res1)
res2()
print("-"*30)
@zsB
@zsA
def test():
print("这是测试函数")
test()
print("-"*30)
------------------------------
zsB执行前...
zsA执行前...
这是测试函数
zsA执行后...
zsB执行后...
------------------------------
zsB执行前...
zsA执行前...
这是测试函数
zsA执行后...
zsB执行后...
------------------------------
5. 带有参数的装饰器
如果原函数带有参数,那么返回的新函数也要带有参数,且参数一一对应
def tool(func):
def log(name,pwd):
print(f"日志记录:【{name}:{pwd}】")
func(name,pwd)
return log
@tool
def login(name,pwd):
print(f"用户名:{name},密码:{pwd}")
login("admin",123456)
日志记录:【admin:123456】
用户名:admin,密码:123456
6. 带返回值的装饰器
如果原函数带有返回值,装饰器也要有返回值,才能将原有函数的执行结果传递出来。
def tool(func):
def log(name, pwd):
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",12345678)
print(res)
日志记录:【admin:12345678】
用户名:admin,密码:12345678
登录失败
7. 定义通用装饰器
增加装饰器的适用性,可以使用可变参数,以保证装饰器能够适用于更多的函数。
def tool(func):
def log(*args,**kwargs):
print(f"日志记录前...")
state = func(*args,**kwargs)
print("日志记录后...")
return state
return log
@tool
def login(name,pwd,fjxx):
print(f"用户名:{name},密码:{pwd},附加信息:{fjxx}")
if name == "admin" and pwd == 123456:
return "登录成功"
return "登录失败"
res = login("admin",12345678,"dadafaaf")
print(res)
日志记录前...
用户名:admin,密码:12345678,附加信息:dadafaaf
日志记录后...
登录失败
8. 使用面向对象的方式定义装饰器
调用时应用call方法调用内部函数
class MyTool:
def __call__(self, func):
return self.tool2(func)
def tool1(func):
def log():
print("log....")
func()
return log
def tool2(self,func):
def check():
print("check....")
func()
return check
@MyTool.tool1
def test():
print("test....")
print("调用方法一:")
test()
@MyTool()
def test():
print("test....")
print("调用方法二:")
test()
调用方法一:
log....
test....
调用方法二:
check....
test....
总结
本篇文章简要介绍了装饰器的基本概念,几种常用装饰器的定义和调用方法。
|