今日主要内容:
1.函数的有用信息
2.带参数的装饰器
3.多个装饰器装饰一个函数
函数的有用信息:
两个内置方法:
1.print(index.__doc__) #查看函数注释的内容
2.print(index.__name__) #查看函数名的方法
例:
def func1():
"""
此函数是完成登陆的功能,参数分别是...作用。
:return: 返回值是登陆成功与否(True,False)
"""
print(666)
print(func1.__name__)
print(func1.__doc__)
当函数引用
使用装饰器传参时,如果是可变的数据类型,则会被动态参数*args,**kwargs等给打散,聚合
所以需要使用wraps 进行解释.
例题:
from functools import wraps
def wrapper(f): # f = func1
@wraps(f) #在最内层函数的正上方
def inner(*args,**kwargs): #聚合
#args (1,2,3)
'''执行函数之前的相关操作'''
ret = f(*args,**kwargs) # 打散 1,2,3
'''执行函数之后的相关操作'''
return ret
return inner
#
# 函数的执行时,*打散。
# 函数的定义时,*聚合。
@wrapper # func1 = wrapper(func1) func1 = inner
def func1(*args): #args (1,2,3)
print(666)
return args
print(func1(*[1,2,3])) # inner(3,5) 打散
带参数的装饰器
下面例题,如果flag 为True则走装饰器,如果是False则不走装饰器.
import time
def timmer(*args,**kwargs):
def wrapper(f):
def inner(*args,**kwargs):
if flag:
start_time = time.time()
ret = f(*args,**kwargs)
time.sleep(0.3)
end_time = time.time()
print('此函数的执行效率%f' % (end_time-start_time))
else:
ret = f(*args, **kwargs)
return ret
return inner
return wrapper
flag = True
@timmer(flag,2,3) # 两步:1,timmer(flag) --> wrapper 2,@wrapper 装饰器
def func1():
print(666)
多个装饰器装饰一个函数
例:
def wrapper1(func): # func == f函数名
def inner1():
print('wrapper1 ,before func') # 2
func()
print('wrapper1 ,after func') # 4
return inner1
def wrapper2(func): # func == inner1
def inner2():
print('wrapper2 ,before func') # 1
func()
print('wrapper2 ,after func') # 5
return inner2
@wrapper2 # f = wrapper2(f) 里面的f==inner1 外面的f == inner2
@wrapper1 # f = wrapper1(f) 里面的f==函数名f 外面的f == inner1
def f(): # 3
print('in f')
f() # inner2()
多装饰器修饰一个函数的流程顺序:
1.先从距离被装饰函数最近的语法糖开始,本例中就是@wrapper1,@wrapper1可以看成 f = wrapper1(f)
2.在算距离被修饰函数第二近的语法糖,本例中就是@wrapper2 @wrapper2 可以看成 f = wrapper2(f)
总结:通过下图可以看成一个基本的方法