from time import time, sleep
def logger(msg=None):
def run_time(func): # 外部闭包函数的参数是被装饰的函数对象 func就是fun_one
print('判断闭包函数1:', run_time.__closure__)
print('func::', func.__name__)
def wrapper(*args, **kwargs):
print('判断闭包函数2:', wrapper.__closure__)
start = time()
func() # 函数在这里运行
end = time()
cost_time = end - start
print("[{}] func three run time {}".format(msg, cost_time))
return wrapper # wrapper返回的是run_time执行后的函数对象
return run_time # 返回的是logger执行后的函数对象
# 闭包定义,内部函数对外部函数**作用域**里的变量的引用。
# 闭包的特点就是内部函数引用了外部函数中的变量。 闭包内的闭包函数私有化了变量,完成了数据的封装
# 函数名.__closure__ 在函数是闭包函数时,返回一个cell元素;不是闭包时,返回None。
@logger(msg="One") # 这里是调用logger函数,并将msg参数传入
def fun_one():
sleep(1)
fun_one()
"""
执行过程:
1、先执行 @logger(msg="One")函数、返回将结果通过return run_time 传给下一层
2、执行def run_time # wrapper返回的是run_time里的执行的结果:并将结果传给下一层
3、执行def wrapper() #它得到了外部函数的所有变量,
返回结果:
判断闭包函数1: (<cell at 0x000002C5F526FD38: str object at 0x000002C5F5243298>, <cell at 0x000002C5F53123D8: function object at 0x000002C5F5473488>)
func:: fun_one
判断闭包函数2: (<cell at 0x000002C5F5312288: function object at 0x000002C5F5473510>, <cell at 0x000002C5F526FD38: str object at 0x000002C5F5243298>, <cell at 0x000002C5F5312438: function object at 0x000002C5F5473598>)
[One] func three run time 1.0097546577453613
"""
闭包原理图:
最简单的装饰器
def func1(func):
def func2():
print ("aaaa")
return func() #执行的是:myprint()
return func2
@func1 #调用方式:func1(myprint())
def myprint():
print ("print1")
myprint()
执行过程:func1(myprint)() #接收被装饰的函数作为参数,而且还要继续调用一次 func2()->print ("aaaa")--->return func() 就是执行:myprint() 打印print ("print1)