Python中為何建議在decorator函數(shù)中使用functools.wraps

以最常見的time_it裝飾器函數(shù)為例龙优, 如下代碼中:

  • 第一個time_it函數(shù)沒有使用functools.wraps, 功能上這個裝飾器并沒有什么問題站绪;

  • 第二個better_time_it在wrapper函數(shù)面前又加了一個@functools.wraps(func)函數(shù)阀参, 其他代碼一致鸣皂;

import time
import functools


def time_it(func):
    def wrapper(*args, **kwargs):
        """This is docs for wrapper"""
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print('Running "%s" in %.3f seconds' % (func.__name__, (end - start)))
        return result

    return wrapper


def better_time_it(func):
    @functools.wraps(func)  # Pay attention here!
    def wrapper(*args, **kwargs):
        """This is docs for wrapper"""
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print('Running "%s" in %.3f seconds' % (func.__name__, (end - start)))
        return result

    return wrapper

我們的測試代碼如下:

@time_it
def foo():
    """This is docs foo function"""
    print('Foo!')

@better_time_it
def yeah():
    """This is docs yeah function"""
    print('Yeah!')

if __name__ == '__main__':
    help(foo)
    help(yeah)

這里我用help函數(shù)查看function的doc strings摔踱,得到如下結(jié)果:

Help on function wrapper in module __main__:

wrapper(*args, **kwargs)
    This is docs for wrapper

Help on function yeah in module __main__:

yeah()
    This is docs yeah function
  • 可以看到使用time_it的foo函數(shù)的docs變成了wrapper函數(shù)的docs虐先;

  • 而使用better_time_it的yeah函數(shù)的docs才是我們期望得到的實際docs;
    不止help函數(shù)的結(jié)果會有變化派敷,因為使用裝飾器實際上返回的并不是原函數(shù)本身蛹批,所以原函數(shù)相關(guān)的metadata信息已經(jīng)變化了,如果不使用functools.wraps函數(shù)就會導(dǎo)致此類副作用,比如序列化和debugger時也會使結(jié)果混亂般眉,所以養(yǎng)成良好的習(xí)慣了赵,自定義decorator的時應(yīng)該盡量使用functools.wraps

關(guān)于functools.wraps()函數(shù)的官方文檔中寫道:

The main intended use for this function is in decorator functions which wrap the decorated function and return the wrapper. If the wrapper function is not updated, the metadata of the returned function will reflect the wrapper definition rather than the original function definition, which is typically less than helpful.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市甸赃,隨后出現(xiàn)的幾起案子柿汛,更是在濱河造成了極大的恐慌,老刑警劉巖埠对,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件络断,死亡現(xiàn)場離奇詭異,居然都是意外死亡项玛,警方通過查閱死者的電腦和手機貌笨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來襟沮,“玉大人锥惋,你說我怎么就攤上這事】” “怎么了膀跌?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長固灵。 經(jīng)常有香客問我捅伤,道長,這世上最難降的妖魔是什么巫玻? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任丛忆,我火速辦了婚禮,結(jié)果婚禮上仍秤,老公的妹妹穿的比我還像新娘熄诡。我一直安慰自己,他們只是感情好徒扶,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布粮彤。 她就那樣靜靜地躺著,像睡著了一般姜骡。 火紅的嫁衣襯著肌膚如雪导坟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天圈澈,我揣著相機與錄音惫周,去河邊找鬼。 笑死康栈,一個胖子當著我的面吹牛递递,可吹牛的內(nèi)容都是我干的喷橙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼登舞,長吁一口氣:“原來是場噩夢啊……” “哼贰逾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起菠秒,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤疙剑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后践叠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體言缤,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年禁灼,在試婚紗的時候發(fā)現(xiàn)自己被綠了管挟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡弄捕,死狀恐怖僻孝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情察藐,我是刑警寧澤皮璧,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布舟扎,位于F島的核電站分飞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏睹限。R本人自食惡果不足惜譬猫,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望羡疗。 院中可真熱鬧染服,春花似錦、人聲如沸叨恨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痒钝。三九已至秉颗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間送矩,已是汗流浹背蚕甥。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留栋荸,地道東北人菇怀。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓凭舶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親爱沟。 傳聞我的和親對象是個殘疾皇子帅霜,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 包(lib)、模塊(module) 在Python中呼伸,存在包和模塊兩個常見概念义屏。 模塊:編寫Python代碼的py...
    清清子衿木子水心閱讀 3,802評論 0 27
  • 直接上正文 函數(shù)是Python內(nèi)建支持的一種封裝闽铐,我們通過把大段代碼拆成函數(shù),通過一層一層的函數(shù)調(diào)用奶浦,就可以把復(fù)雜...
    OzanShareing閱讀 448評論 0 0
  • 半夜+一個清晨看完這本書兄墅,感覺就是一個字 堵 。小人物的悲喜串成了整個時代澳叉,他們的命運如同巨大機器下的齒輪隙咸,千...
    Jasmyn1閱讀 584評論 3 3
  • 最近找了一份實習(xí),工作的性質(zhì)偏銷售成洗,跟我的專業(yè)并不相關(guān)五督,但是公司是一家世界五百強,總體來說還可以瓶殃。 但是身邊的同事...
    北海道的北閱讀 470評論 0 0
  • 第三章 查案2 按第五遍門鈴的時候充包,門突然被打開了,出現(xiàn)在門內(nèi)的是安瑜遥椿。劉劍看到安瑜明顯愣了一下基矮,接著變得緊張起來...
    白寧紀事閱讀 242評論 0 2