一、前提概念
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看的興奮了,睡不著,覺得今天得記錄下,所以寫了這篇文章,不足或錯誤之處,請大家指正,謝謝!
參考文章
How can I make a chain of function decorators in Python
Python in Practice
http://www.sharejs.com/codes/python/8361
疑問:如果一個作者,在一個網站上發表了文章,如果需要在另一個網站上再發表,需不需要聲明成轉載或是需要其他什么的說明,麻煩解答一下。
附:本人簡書地址
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/45436.html
摘要:所以,有另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。 對于已經對 閉包 或者 裝飾器有一定概念的,可以直接通過右側標題目錄直接定位到相應段落查看所需的內容。 什么是裝飾器? 裝飾器(Decorator)相對簡單,咱們先介紹它:裝飾器的功能是將被裝飾的函數當作參數傳遞給與裝飾器對應的函數(名稱相同的函數),并返回包裝后的被裝飾的函數,聽起來有點繞,沒關系,直接看示意圖,...
摘要:首先說函數,在官方文檔的描述中,這個函數的聲明如下。這是因為給添加上修飾器相當于執行了一句,執行完這條語句之后,函數就變成了函數。自定義修飾器我們對上面定義的修飾器稍作修改,添加了一句。參考鏈接裝飾器和模塊源碼 預備知識 在了解wraps修飾器之前,我們首先要了解partial和update_wrapper這兩個函數,因為在wraps的代碼中,用到了這兩個函數。 partial 首先說...
摘要:本文從裝飾模式出發,聊聊中的裝飾器和注解。該函數的函數名。不提供元數據的支持。中的元數據操作可以通過包來實現對于元數據的操作。 ??隨著Typescript的普及,在KOA2和nestjs等nodejs框架中經??吹筋愃朴趈ava spring中注解的寫法。本文從裝飾模式出發,聊聊Typescipt中的裝飾器和注解。 什么是裝飾者模式 Typescript中的裝飾器 Typescr...
摘要:的裝飾器是用來裝飾函數的。簡單裝飾器裝飾器的語法糖是使用符號表示,裝飾器本身也是一個函數,只不過參數是函數而已。保留函數的元信息被修飾之后的函數,它的元信息都消失,被替換的函數代替。中提供了來保存函數的元信息。 python的裝飾器是用來裝飾函數的。這是什么意思呢?假如我們有一個函數,這個函數的功能不能滿足我們現有的需求,那么我們可以通過裝飾器在這個函數執行前執行后做一些我們需要的操作...
摘要:然后煎魚加了一個后再調用函數,得到的輸出結果和加修飾器的一樣,換言之等效于因此,我們對于,可以理解是,它通過閉包的方式把新函數的引用賦值給了原來函數的引用。 Python有什么好學的這句話可不是反問句,而是問句哦。 主要是煎魚覺得太多的人覺得Python的語法較為簡單,寫出來的代碼只要符合邏輯,不需要太多的學習即可,即可從一門其他語言跳來用Python寫(當然這樣是好事,誰都希望入門簡...
閱讀 3313·2023-04-26 00:58
閱讀 1268·2021-09-22 16:04
閱讀 3311·2021-09-02 15:11
閱讀 1554·2019-08-30 15:55
閱讀 2339·2019-08-30 15:55
閱讀 3248·2019-08-23 18:41
閱讀 3458·2019-08-23 18:18
閱讀 2752·2019-08-23 17:53