一、前提概念
Python中的函數(shù)是對(duì)象。也因此,函數(shù)可以被當(dāng)做變量使用。
二、代碼模型以下代碼片段來(lái)自于: http://www.sharejs.com/codes/python/8361
# -*- coding: utf-8 -*- from threading import Thread import time class TimeoutException(Exception): pass ThreadStop = Thread._Thread__stop#獲取私有函數(shù) 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)過(guò)程:
執(zhí)行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
通過(guò)函數(shù)timelimited(2),可以看到最后返回了decorator函數(shù),其內(nèi)部參數(shù)timeout即為2.此時(shí)@timelimited(2)可以看成是@decorator
@decorator
@decorator def somefunction(secs):
python解析器遇到@,且后面跟著函數(shù)時(shí),會(huì)把函數(shù)somefunction當(dāng)做參數(shù)傳遞給decorator函數(shù)并執(zhí)行,即decorator(somefunction),本例中執(zhí)行 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
此例中,執(zhí)行 decorator(fn_1)后返回的是decorator2,decorator2中function參數(shù)為fn_1對(duì)象,
最后用返回的decorator2函數(shù)替換somefunction,本例中是用decorator2替換了原來(lái)的fn_1
因此,后面直接調(diào)用fn_1(4)時(shí),就是調(diào)用了decorator2(4),再在decorator2執(zhí)行過(guò)程中,把參數(shù)傳給function函數(shù)變量執(zhí)行,最后返回想要的結(jié)果。
吐槽一下:感覺示例代碼中的decorator2命名為wrapper會(huì)更合適一點(diǎn)
昨晚看Python in Practice看的興奮了,睡不著,覺得今天得記錄下,所以寫了這篇文章,不足或錯(cuò)誤之處,請(qǐng)大家指正,謝謝!
參考文章
How can I make a chain of function decorators in Python
Python in Practice
http://www.sharejs.com/codes/python/8361
疑問:如果一個(gè)作者,在一個(gè)網(wǎng)站上發(fā)表了文章,如果需要在另一個(gè)網(wǎng)站上再發(fā)表,需不需要聲明成轉(zhuǎn)載或是需要其他什么的說(shuō)明,麻煩解答一下。
附:本人簡(jiǎn)書地址
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/45436.html
摘要:所以,有另一種說(shuō)法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。 對(duì)于已經(jīng)對(duì) 閉包 或者 裝飾器有一定概念的,可以直接通過(guò)右側(cè)標(biāo)題目錄直接定位到相應(yīng)段落查看所需的內(nèi)容。 什么是裝飾器? 裝飾器(Decorator)相對(duì)簡(jiǎn)單,咱們先介紹它:裝飾器的功能是將被裝飾的函數(shù)當(dāng)作參數(shù)傳遞給與裝飾器對(duì)應(yīng)的函數(shù)(名稱相同的函數(shù)),并返回包裝后的被裝飾的函數(shù),聽起來(lái)有點(diǎn)繞,沒關(guān)系,直接看示意圖,...
摘要:首先說(shuō)函數(shù),在官方文檔的描述中,這個(gè)函數(shù)的聲明如下。這是因?yàn)榻o添加上修飾器相當(dāng)于執(zhí)行了一句,執(zhí)行完這條語(yǔ)句之后,函數(shù)就變成了函數(shù)。自定義修飾器我們對(duì)上面定義的修飾器稍作修改,添加了一句。參考鏈接裝飾器和模塊源碼 預(yù)備知識(shí) 在了解wraps修飾器之前,我們首先要了解partial和update_wrapper這兩個(gè)函數(shù),因?yàn)樵趙raps的代碼中,用到了這兩個(gè)函數(shù)。 partial 首先說(shuō)...
摘要:本文從裝飾模式出發(fā),聊聊中的裝飾器和注解。該函數(shù)的函數(shù)名。不提供元數(shù)據(jù)的支持。中的元數(shù)據(jù)操作可以通過(guò)包來(lái)實(shí)現(xiàn)對(duì)于元數(shù)據(jù)的操作。 ??隨著Typescript的普及,在KOA2和nestjs等nodejs框架中經(jīng)常看到類似于java spring中注解的寫法。本文從裝飾模式出發(fā),聊聊Typescipt中的裝飾器和注解。 什么是裝飾者模式 Typescript中的裝飾器 Typescr...
摘要:的裝飾器是用來(lái)裝飾函數(shù)的。簡(jiǎn)單裝飾器裝飾器的語(yǔ)法糖是使用符號(hào)表示,裝飾器本身也是一個(gè)函數(shù),只不過(guò)參數(shù)是函數(shù)而已。保留函數(shù)的元信息被修飾之后的函數(shù),它的元信息都消失,被替換的函數(shù)代替。中提供了來(lái)保存函數(shù)的元信息。 python的裝飾器是用來(lái)裝飾函數(shù)的。這是什么意思呢?假如我們有一個(gè)函數(shù),這個(gè)函數(shù)的功能不能滿足我們現(xiàn)有的需求,那么我們可以通過(guò)裝飾器在這個(gè)函數(shù)執(zhí)行前執(zhí)行后做一些我們需要的操作...
摘要:然后煎魚加了一個(gè)后再調(diào)用函數(shù),得到的輸出結(jié)果和加修飾器的一樣,換言之等效于因此,我們對(duì)于,可以理解是,它通過(guò)閉包的方式把新函數(shù)的引用賦值給了原來(lái)函數(shù)的引用。 Python有什么好學(xué)的這句話可不是反問句,而是問句哦。 主要是煎魚覺得太多的人覺得Python的語(yǔ)法較為簡(jiǎn)單,寫出來(lái)的代碼只要符合邏輯,不需要太多的學(xué)習(xí)即可,即可從一門其他語(yǔ)言跳來(lái)用Python寫(當(dāng)然這樣是好事,誰(shuí)都希望入門簡(jiǎn)...
閱讀 3358·2023-04-26 00:58
閱讀 1290·2021-09-22 16:04
閱讀 3349·2021-09-02 15:11
閱讀 1591·2019-08-30 15:55
閱讀 2369·2019-08-30 15:55
閱讀 3330·2019-08-23 18:41
閱讀 3488·2019-08-23 18:18
閱讀 2779·2019-08-23 17:53