一、前提概念
Python中的函数是对象。也因此,函数可以被当做变量使用。
二、代码模型
以下代码片段来自于: http://www.sharejs.com/codes/python/8361
# -*- coding: utf-8 -*-
from threading import Thread
import time
class TimeoutException(Exception):
pass
ThreadStop = Thread._Thread__stop#获取私有函数
def timelimited(timeout):
def decorator(function):
def decorator2(*args,**kwargs):
class TimeLimited(Thread):
def __init__(self,_error= None,):
Thread.__init__(self)
self._error = _error
def run(self):
try:
self.result = function(*args,**kwargs)
except Exception,e:
self._error =e
def _stop(self):
if self.isAlive():
ThreadStop(self)
t = TimeLimited()
t.start()
t.join(timeout)
if isinstance(t._error,TimeoutException):
t._stop()
raise TimeoutException('timeout for %s' % (repr(function)))
if t.isAlive():
t._stop()
raise TimeoutException('timeout for %s' % (repr(function)))
if t._error is None:
return t.result
return decorator2
return decorator
@timelimited(2)
def fn_1(secs):
time.sleep(secs)
return 'Finished'
if __name__ == "__main__":
print fn_1(4)
三、分析代码片段
@timelimited(2)
def fn_1(secs):
time.sleep(secs)
return 'Finished'
解析@timelimited(2)过程:
执行timelimited(2)
def timelimited(timeout):
def decorator(function):
def decorator2(*args,**kwargs):
.......
t.join(timeout)
if isinstance(t._error,TimeoutException):
t._stop()
raise TimeoutException('timeout for %s' % (repr(function)))
if t.isAlive():
t._stop()
raise TimeoutException('timeout for %s' % (repr(function)))
if t._error is None:
return t.result
return decorator2
return decorator
通过函数timelimited(2),可以看到最后返回了decorator函数,其内部参数timeout即为2.此时@timelimited(2)可以看成是@decorator
@decorator
@decorator
def somefunction(secs):
python解析器遇到@,且后面跟着函数时,会把函数somefunction当做参数传递给decorator函数并执行,即decorator(somefunction),本例中执行 decorator(fn_1)
def decorator(function):
def decorator2(*args,**kwargs):
.......
t.join(timeout)
if isinstance(t._error,TimeoutException):
t._stop()
raise TimeoutException('timeout for %s' % (repr(function)))
if t.isAlive():
t._stop()
raise TimeoutException('timeout for %s' % (repr(function)))
if t._error is None:
return t.result
return decorator2
此例中,执行 decorator(fn_1)后返回的是decorator2,decorator2中function参数为fn_1对象,
最后用返回的decorator2函数替换somefunction,本例中是用decorator2替换了原来的fn_1
因此,后面直接调用fn_1(4)时,就是调用了decorator2(4),再在decorator2执行过程中,把参数传给function函数变量执行,最后返回想要的结果。
吐槽一下:感觉示例代码中的decorator2命名为wrapper会更合适一点
昨晚看Python in Practice看的兴奋了,睡不着,觉得今天得记录下,所以写了这篇文章,不足或错误之处,请大家指正,谢谢!
参考文章
Python in Practice
疑问:
如果一个作者,在一个网站上发表了文章,如果需要在另一个网站上再发表,需不需要声明成转载或是需要其他什么的说明,麻烦解答一下。
附:本人简书地址
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。