[Python] 闭包函数和装饰器的疑问
今天看书上的例子:
from time import ctime, sleep
def tsfunc(func):
def wrappedFunc():
print '[%s] %s() is called' % (ctime(),func.__name__)
return func()
return wrappedFunc
@tsfunc
def foo():
pass
foo()
sleep(4)
for i in range(2):
sleep(1)
foo()
输出的结果是好理解的:
eric@laptop ~/kuaipan/testcode $ python deco.py
[Tue Mar 15 22:46:32 2016] foo() called
[Tue Mar 15 22:46:37 2016] foo() called
[Tue Mar 15 22:46:38 2016] foo() called
我看了这个例子的第一念头产生的疑问是:
第三行的def wrappedFunc():
和第六行的return wrappedFunc
是多余的?
所以怀着这样的想法,试了一下:
from time import ctime,sleep
def tsfunc(func):
#def wrappedFunc():
print '[%s] %s() called' % (ctime(), func.__name__)
return func
#return wrappedFunc
@tsfunc
def foo():
pass
foo()
sleep(4)
for i in range(2):
sleep(1)
foo()
结果,只返回了一次结果:
eric@laptop ~/kuaipan/testcode $ python deco.py
[Tue Mar 15 22:50:13 2016] foo() called
eric@laptop ~/kuaipan/testcode $
为了弄清楚发生了什么,我在控制台一行一行的执行代码,结果如下:
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from time import ctime,sleep
>>> def tsfunc(func):
... print '[%s] %s() called' % (ctime(),func.__name__)
... return func
...
>>> @tsfunc
... def foo():
... pass
...
[Tue Mar 15 10:21:27 2016] foo() called
>>> foo
<function foo at 0x7f6416c885f0>
>>> foo()
>>> foo()
>>> print foo()
None
从过程看来,foo()只是在定义@tsfunc
时被立刻装饰了一次,后边再调用foo()时就只是调用了foo本身了,这是为什么???
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
整个程序很好理解,我们一步步来拆解:
@tsfunc
其实等同于foo = tsfunc(foo)
,因此你的程序等同于:此时对于
foo = tsfunc(foo)
,由于tsfunc
返回的是wrappedFunc
,因此foo = tsfunc(foo)
等同于foo = wrappedFunc
,需要注意的是tsfunc
调用时并不会被打印任何语句,因为tsfunc
的局部作用域内并无print
,而只有foo()
执行时才会打印wrappedFunc()
内的print
,所以你调用foo()
三次,则打印了三次,因此最终这段程序可以等同于:而当去除第三行和第六行后,情况就不一样了,首先仍然改写下
@tsfunc
,程序为:对于
foo = tsfunc(foo)
由于tsfunc(foo)
最终返回的是传入的参数foo
,所以foo = tsfunc(foo)
等价于foo = foo
,而print
其实只是在@tsfunc
被调用那次,执行了一次打印,由于foo
本身本就只有一个'pass'因此不管你下面调用多少次foo()
,只会输出tsfunc
被调用那次的print
,因此最终程序等同于:其实你的示例涉及到装饰器和闭包函数的内容,对于这两者的作用可以参看这篇文章:
Python 的闭包和装饰器