#装饰器==高阶函数+嵌套函数
在不改变函数调用方式的基础上在函数的前,后添加功能,这就是装饰器的作用!!!!
import time
from functools import wraps
#functools.wraps 的作用是将原函数对象的指定属性复制给包装函数对象, 默认有 module、name、doc,或者通过参数选择
# kill函数包含kerr函数,这个就是嵌套函数;kerr函数返回的是kerr函数的内存地址,这个就是高阶函数
def kill(func): # 用来装饰test1函数的
@wraps(func) # 目的是可以查看原函数的一些信息,比如注释内容什么的
def kerr(*args, **kwargs): # 可以接受多个参数
"""我是kerr函数的注释"""
start_time = time.time() # 开始时间
func(*args, **kwargs) # 被装饰函数
end_time = time.time() # 结束时间
print("this is %s ,timing is %s" % (func, (end_time - start_time))) # 可以把这行理解是为test1函数新增加的功能
return kerr # 返回kerr函数的内存地址
@kill
def test1(name, name1): # 被装饰函数
print(test1)
time.sleep(1)
print(" in the test1 。。。。,name is %s" % name,name1)
# test1 = kill(test1)
test1("333", "111") # 调用的名字虽然和被装饰函数一样,但是实际调用的kerr函数( kill(test1) ),因为现在test1指向的是kerr的内存地址
print(test1.__doc__) # 查看test1函数的注释,其实看的是kerr函数注释
print (test1.__name__) # 查看test1的函数名称,看的是kerr函数名
@kill
#其实就是等于test1 = kill(test1),先运行kill函数,得到一个kerr函数的内存地址,因为装饰的是test1,所以把值赋给了test1,这个时候其实加上“()”就可以运行kerr函数,kerr函数里面又有被装饰的函数,所以调用kerr也调用了test1的函数
如果在函数kerr正上方不写@wraps的话,那么运行print(test1 .__ doc __)#查看的就不是原代码test1函数的注释,而是kerr函数的注释。同理运行print(test1 .__ name__)#查看的也不是测试1的函数名称,而是kerr函数的名称
可以试一下!