Python中的函數是對象。也所以,函數能夠被當作變量使用。python
如下代碼片斷來自於: http://www.sharejs.com/codes/python/8361app
# -*- 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)能夠當作是@decoratorcode
@decorator對象
@decorator def somefunction(secs):
python解析器遇到@,且後面跟着函數時,會把函數somefunction當作參數傳遞給decorator函數並執行,即decorator(somefunction),本例中執行 decorator(fn_1)utf-8
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對象,get
最後用返回的decorator2函數替換somefunction,本例中是用decorator2替換了原來的fn_1it
所以,後面直接調用fn_1(4)時,就是調用了decorator2(4),再在decorator2執行過程當中,把參數傳給function函數變量執行,最後返回想要的結果。io
吐槽一下:感受示例代碼中的decorator2命名爲wrapper會更合適一點
昨晚看Python in Practice看的興奮了,睡不着,以爲今天得記錄下,因此寫了這篇文章,不足或錯誤之處,請你們指正,謝謝!
參考文章
Python in Practice
若是一個做者,在一個網站上發表了文章,若是須要在另外一個網站上再發表,需不須要聲明成轉載或是須要其餘什麼的說明,麻煩解答一下。
附:本人簡書地址