python
为什么要用装饰器
装饰器用来不修改代码前提下,扩展功能
装饰器只能给函数用
def Debug(func): #将addUser 传给debug的形参func debug返回wrapper
# 然后执行wrapper的print 在执行addUser
def wrapper():
print("当前执行函数为:{0}".format(func.__name__))# 输出执行函数的名字
func() #当前执行的函数
return wrapper #回调执行wrapper函数,不能加括号加上就执行了
@Debug #debug(addUser)()
# #加上装饰器在执行函数时根据结果可以知道是在执行那个函数
def addUser():
print('添加用户成功')
def reistUser():
print('添加用户成功')
addUser()
回调函数
回调函数案例
def add(a,b):
c=a+b
return c
def display_result(a,b):
res=add(a,b) #将10,20给display_result函数,display_result函数调用add函数
#add函数将结果回调给display_result函数
print(res)
display_result(10,20)
display_result#表示函数名或变量,函数所在的地址
display_result()#表示执行函数
闭包
def debug(func): #将addUser 传给debug的形参func 先执行wrapper的print 在执行addUser
def wrapper():
print("[DEBUG]:enter{}()".format(func.__name__))
func()
return wrapper
def show():
print('hello')
debug(show)()
装饰器传参和返回值
def log(func): #将addUser交给func
from datetime import datetime
def wrapper(m,*args): #m,*args为添加的用户可以添加多个,因为有可变参数
print('当前执行的代码是:',func.__name__)
print('添加用户是:',m,*args)
dd=datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print('添加时间是:',dd)
return func(m) # 必须要写return 因为addUser里面有返回值
return wrapper
@log
def addUser(user):
if user:
return True
else:
return False
a=addUser('qw','12')
print(a)
多个装饰器
def A(func):
def warrper():
print('a')
func()
print('b')
return warrper
def B(func):
def warrper():
print('c')
func()
print('d')
return warrper
@A
@B
def show():
print('show is')
show()##a c show is d b 先执行@A 输出print a 到func 时 发现还有一个@B 就会执行@B
# 输出print c 然后执行@B里的函数 再执行print d 最后回到A 执行print b 。
# 只会执行最下面@B里的func
带参数的装饰器
def log(*log_args):#普通方法 不是装饰器
def decorated(func): #decorated才是装饰器
from datetime import datetime
def warrper(m):
print('当前执行的函数是:',func.__name__)
dd=datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print('添加时间为:',dd)
print('添加的用户是:',m)
print(func(m)) #为了输出原函数的结果
return warrper
return decorated
@log() #log()返回值decorated是装饰器,log必须带括号使装饰器执行,
#可以给装饰器存参数
def A(user):
if user:
return True
else:
return False
A('qw')
demo
log不带参数
def log(*log_args):
def decorated(func):
from datetime import datetime
def wrappwer(m):
from fileHlper import saveFile
dd = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
txt='\n当前执行的代码是:'+func.__name__+'\n添加用户是:'+m+'\n执行时间是:'+dd +'\n'+str(func(m))
saveFile('p.txt', txt)
#func(m)
# return func(m) #想得到原函数的结果可以在这里用renturn func(m) 但结果必须加上print(res)
#才能得到Ture 因为return 返回结果 必须要print才能看到
# print(func(m)) #也可以用print(func(m)) 这时最后不用加print(res) 因为print已经输出结果了
return wrappwer
return decorated
@log()
def addUser(user):
if user:
#添加用户省略...
return True
else:
return False
res = addUser('qw')
print(res)
log带参数
def log(*log_args):
def decorated(func):
from datetime import datetime
def wrappwer(m):
from fileHlper import saveFile
dd = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
txt='\n当前执行的代码是:'+func.__name__+'\n添加用户是:'+m+'\n执行时间是:'+dd +'\n'+str(func(m))
print(log_args) #('D:\\D\\p.txt',) logs_args里的参数放在一个元组里面,所以下面要用[0]表示写在第一个路径下
#若log里面有两个参数 则[1]表示将文件写在第二个路径下
saveFile(log_args[0], txt)
return wrappwer
return decorated
@log('D:\QWE\p.txt') #('D:\QWE\p.txt','D:\ABC\p.txt')
def addUser(user):
if user:
#添加用户省略...
return True
else:
return False
addUser('w')