foo = timeit(foo) #可以直接写成@timeit + foo定义,python的"语法糖"
@timeit
def foo():
pass
实际上解释器解释成“foo = timeit(foo)”来执行
一、
修饰器timeit(),用了内嵌函数wrapper()来修饰目标函数foo(),并返回了修饰后的函数wrapper()对象;
通过语法糖代码,解释器把返回的函数对象赋值给foo,即foo = wrapper;
函数foo()和wrapper()在此修饰过程中并没有被实例化,所以不会有输出,需要实例化foo()才会有输出。
二、
修饰器test(),最后return func,即返回了原函数foo,即foo = foo,实例化foo(),输出的为未修饰的值。
三、
修饰器test1(),可以看出修饰的过程:上面说过了,语法糖@test1 + foo定义,实际上即foo = test1(foo),再执行过程中,函数test1(foo)被实例化,参数为函数foo,所以“我是第一层主函数test1”被首先输出,然后返回内嵌函数wrapper,并赋值给foo,即foo这个名称现在指向的是函数wrapper对象,即原来foo的代码被wrapper的代码替换了;
所以,实例化foo(),输出的为“我是内嵌函数wrapper”。
四、
修饰器test2(),没有内嵌函数,所以,在修饰过程中,函数test2的代码被执行,func(),即函数foo()被实例化,所以输出“我是被修饰的函数foo()”,然后print,打印出开始和结束的时间,最后返回原函数。
五、
修饰器test3(),最后没有return,即返回空值,所以最后foo 为空值,就没法实例化;
执行到foo()实例化时报错“TypeError: ‘NoneType’ object is not callable”
import time
def timeit(func):
def wrapper():
start = time.time()
func()
end = time.time()
print("start:", start, " end:", end)
return wrapper
def test(func):
def wrapper():
start = time.time()
func()
end = time.time()
print("start:", start, " end:", end)
return func
def test1(func):
def wrapper():
print('我是内嵌函数wrapper')
pass
print('我是第一层主函数test1')
return wrapper
def test2(func):
start = time.time()
func()
end = time.time()
print("start:", start, " end:", end)
return func
def test3(func):
start = time.time()
func()
end = time.time()
print("start:", start, " end:", end)
def foo_():
print("我是被修饰的函数foo()")
def main(wrapper):
@wrapper
def foo():
foo_()
print('第一次运行修饰后的函数')
foo()
print('再次运行修饰后的函数')
foo()
def main1(wrapper):
foo = wrapper(foo_)
print('第一次运行修饰后的函数')
foo()
print('再次运行修饰后的函数')
foo()
main(timeit)
第一次运行修饰后的函数
我是被修饰的函数foo()
start: 1591341658.6980152 end: 1591341658.6990144
再次运行修饰后的函数
我是被修饰的函数foo()
start: 1591341658.701015 end: 1591341658.7020152
main1(timeit)
第一次运行修饰后的函数
我是被修饰的函数foo()
start: 1591341658.7720187 end: 1591341658.7720187
再次运行修饰后的函数
我是被修饰的函数foo()
start: 1591341658.7740178 end: 1591341658.7750182
main(test)
第一次运行修饰后的函数
我是被修饰的函数foo()
再次运行修饰后的函数
我是被修饰的函数foo()
main(test1)
我是第一层主函数test1
第一次运行修饰后的函数
我是内嵌函数wrapper
再次运行修饰后的函数
我是内嵌函数wrapper
main(test2)
我是被修饰的函数foo()
start: 1591341659.01184 end: 1591341659.012841
第一次运行修饰后的函数
我是被修饰的函数foo()
再次运行修饰后的函数
我是被修饰的函数foo()
main(test3)
我是被修饰的函数foo()
start: 1591341659.0871117 end: 1591341659.0881119
第一次运行修饰后的函数
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-7de597082dfe> in <module>
----> 1 main(test3)
<ipython-input-1-03f14ba954dc> in main(wrapper)
48 foo_()
49 print('第一次运行修饰后的函数')
---> 50 foo()
51 print('再次运行修饰后的函数')
52 foo()
TypeError: 'NoneType' object is not callable