[python] 裝飾器學習

很多python的代碼都帶有裝飾器=。=
現(xiàn)在不學以后也要學
學一下裝飾器

閉包

在學裝飾器之前先看看python的閉包

在一些語言中泥张,在函數(shù)中可以(嵌套)定義另一個函數(shù)時,如果內(nèi)部的函數(shù)引用了外部的函數(shù)的變量鞠值,則可能產(chǎn)生閉包媚创。閉包可以用來在一個函數(shù)與一組“私有”變量之間創(chuàng)建關聯(lián)關系。在給定函數(shù)被多次調(diào)用的過程中彤恶,這些私有變量能夠保持其持久性钞钙。
—— 維基百科)

def make_printer(msg):
    def printer():
        print msg  # 夾帶私貨(外部變量)
    return printer  # 返回的是函數(shù),帶私貨的函數(shù)

printer = make_printer('Foo!')
printer()

閉包就是當某個函數(shù)被當成對象返回時粤剧,夾帶了外部變量歇竟,就形成了一個閉包。

而如果內(nèi)部函數(shù)里引用了外部函數(shù)里定義的對象(甚至是外層之外抵恋,但不是全局變量)焕议,那么此時內(nèi)部函數(shù)就被稱為閉包函數(shù)。閉包函數(shù)所引用的外部定義的變量被叫做自由變量弧关。閉包從語法上看非常簡單盅安,但是卻有強大的作用。閉包可以將其自己的代碼和作用域以及外部函數(shù)的作用結合在一起世囊。下面給出一個簡單的閉包的例子:

def count(a):
    b = 1
    def sum():
        c = 1
        return a + c  # a是自由變量
    return sum

print count(a = 2)() # 3

裝飾器

python裝飾器本質(zhì)上就是一個函數(shù)别瞭,它可以讓其他函數(shù)在不需要做任何代碼變動的前提下增加額外的功能,裝飾器的返回值也是一個函數(shù)對象(函數(shù)的指針)

裝飾器的屬性

  • 實質(zhì): 是一個函數(shù)
  • 參數(shù):是你要裝飾的函數(shù)名(并非函數(shù)調(diào)用)
  • 返回:是裝飾完的函數(shù)名(也非函數(shù)調(diào)用)
  • 作用:為已經(jīng)存在的對象添加額外的功能
  • 特點:不需要對對象做任何的代碼上的變動

python裝飾器有很多經(jīng)典的應用場景株憾,比如:插入日志蝙寨、性能測試、事務處理嗤瞎、權限校驗等墙歪。裝飾器是解決這類問題的絕佳設計。并且從引入中的列子中我們也可以歸納出:裝飾器最大的作用就是對于我們已經(jīng)寫好的程序贝奇,我們可以抽離出一些雷同的代碼組建多個特定功能的裝飾器虹菲,這樣我們就可以針對不同的需求去使用特定的裝飾器,這時因為源碼去除了大量泛化的內(nèi)容而使得源碼具有更加清晰的邏輯

裝飾器也分為函數(shù)裝飾器和類裝飾器

在python2.4之前的裝飾器是這樣的

def debug(func):
    def wrapper():
        print "[DEBUG]: enter {}()".format(func.__name__)
        return func()
    return wrapper

def say_hello():
    print "hello!"

say_hello = debug(say_hello)  # 添加功能并保持原函數(shù)名不變

其實裝飾器的原理就跟這個差不多他返回的就是wrapper 會把原來的覆蓋了


-w468

跟現(xiàn)在的裝飾器的意思是一樣的

def debug(func):
    def wrapper():
        print "[DEBUG]: enter {}()".format(func.__name__)
        return func()
    return wrapper

@debug
def say_hello():
    print "hello!"

只不過更加簡便少了一步賦值的步驟

函數(shù)裝飾器

上面的都是函數(shù)裝飾器

def debug(func):
    def wrapper():
        print "[DEBUG]: enter {}()".format(func.__name__)
        return func()
    return wrapper

@debug
def say_hello():
    print "hello!"
    
say_hello()

類裝飾器

裝飾器函數(shù)其實是這樣一個接口約束掉瞳,它必須接受一個callable對象作為參數(shù)毕源,然后返回一個callable對象浪漠。在Python中一般callable對象都是函數(shù)
只要當前的類中有一個__call__函數(shù)就可以讓該對象編程callable對象
只要用__init__來初始化, __call__來返回函數(shù)就可以了

class debug():
    def __init__(self, func):
        self.func = func

    def __call__(self):
        print "[DEBUG]: enter {func}()".format(
            func=self.func.__name__)
        return self.func()
@debug
def say_hello():
    print "say hello!"

say_hello()

這樣就好了
跟原來的函數(shù)裝飾器差不多

參考鏈接

https://betacat.online/posts/2016-10-23/python-closure/
https://www.cnblogs.com/cicaday/p/python-decorator.html

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市霎褐,隨后出現(xiàn)的幾起案子址愿,更是在濱河造成了極大的恐慌,老刑警劉巖瘩欺,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件必盖,死亡現(xiàn)場離奇詭異拌牲,居然都是意外死亡俱饿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門塌忽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拍埠,“玉大人,你說我怎么就攤上這事土居≡婀海” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵擦耀,是天一觀的道長棉圈。 經(jīng)常有香客問我,道長眷蜓,這世上最難降的妖魔是什么分瘾? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮吁系,結果婚禮上德召,老公的妹妹穿的比我還像新娘。我一直安慰自己汽纤,他們只是感情好上岗,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蕴坪,像睡著了一般肴掷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上背传,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天呆瞻,我揣著相機與錄音,去河邊找鬼续室。 笑死栋烤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的挺狰。 我是一名探鬼主播明郭,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼买窟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了薯定?” 一聲冷哼從身側(cè)響起始绍,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎话侄,沒想到半個月后亏推,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡年堆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年吞杭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片变丧。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡芽狗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出痒蓬,到底是詐尸還是另有隱情朱灿,我是刑警寧澤舌剂,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布酿雪,位于F島的核電站奏瞬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鲁捏。R本人自食惡果不足惜芯砸,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碴萧。 院中可真熱鬧乙嘀,春花似錦、人聲如沸破喻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽曹质。三九已至婴噩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間羽德,已是汗流浹背几莽。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宅静,地道東北人章蚣。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像姨夹,于是被迫代替她去往敵國和親纤垂。 傳聞我的和親對象是個殘疾皇子矾策,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

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

  • 包(lib)、模塊(module) 在Python中峭沦,存在包和模塊兩個常見概念贾虽。 模塊:編寫Python代碼的py...
    清清子衿木子水心閱讀 3,806評論 0 27
  • 閉包和裝飾器 1.8 閉包和裝飾器 學習目標 1. 能夠說出閉包的定義形式 2. 能夠說出裝飾器的實現(xiàn)形式 ...
    Cestine閱讀 538評論 0 0
  • 本文為《爬著學Python》系列第四篇文章。從本篇開始吼鱼,本專欄在順序更新的基礎上蓬豁,會有不規(guī)則的更新。 在Pytho...
    SyPy閱讀 2,502評論 4 11
  • 一支獨秀 錦繡初迎季領頭菇肃, 惹來綠意競風流地粪。 同生一體存溫暖, 香侵清風潤萬喉巷送。 艷爭春 又是花開...
    商亞萍閱讀 465評論 5 9
  • BFC全稱是Block Formatting Context驶忌,即塊格式化上下文矛辕。它是CSS2.1規(guī)范定義的笑跛,關于C...
    xf0128閱讀 337評論 0 0