黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

python閉包與裝飾器

系統(tǒng) 2252 0

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

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

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

閉包在Python中很常見(jiàn),只不過(guò)你沒(méi)特別注意這就是一個(gè)閉包。比如Python中的裝飾器Decorator,假如你需要寫(xiě)一個(gè)帶參數(shù)的裝飾器,那么一般都會(huì)生成閉包

            
              #不帶參數(shù)的裝飾器
def debug(func):
    def wrapper(*args, **kwargs):  # 指定宇宙無(wú)敵參數(shù)
        print "[DEBUG]: enter {}()".format(func.__name__)
        print 'Prepare and say...',
        return func(*args, **kwargs)
    return wrapper  # 返回

@debug
def say(something):
    print "hello {}!".format(something)
            
          

?

帶參數(shù)的裝飾器:

            
              def logging(level):
    def wrapper(func):
        def inner_wrapper(*args, **kwargs):
            print "[{level}]: enter function {func}()".format(
                level=level,
                func=func.__name__)
            return func(*args, **kwargs)
        return inner_wrapper
    return wrapper

@logging(level='INFO')
def say(something):
    print "say {}!".format(something)

# 如果沒(méi)有使用@語(yǔ)法,等同于
# say = logging(level='INFO')(say)

@logging(level='DEBUG')
def do(something):
    print "do {}...".format(something)

if __name__ == '__main__':
    say('hello')
    do("my work")
            
          

如果你的裝飾器如果帶參數(shù),就需要在原來(lái)的裝飾器上再包一層,用于接收這些參數(shù)。這些參數(shù)(私貨)傳遞到內(nèi)層的裝飾器里后,閉包就形成了。所以說(shuō)當(dāng)你的裝飾器需要自定義參數(shù)時(shí),一般都會(huì)形成閉包。(類(lèi)裝飾器例外)

類(lèi)裝飾器

            
              class logging(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print "[DEBUG]: enter function {func}()".format(
            func=self.func.__name__)
        return self.func(*args, **kwargs)
@logging
def say(something):
    print "say {}!".format(something)
            
          

__call__ 這樣前后都帶下劃線(xiàn)的方法在Python中被稱(chēng)為內(nèi)置方法,有時(shí)候也被稱(chēng)為魔法方法。

帶參數(shù)的類(lèi)裝飾器:

            
              class logging(object):
    def __init__(self, level='INFO'):
        self.level = level
        
    def __call__(self, func): # 接受函數(shù)
        def wrapper(*args, **kwargs):
            print "[{level}]: enter function {func}()".format(
                level=self.level,
                func=func.__name__)
            func(*args, **kwargs)
        return wrapper  #返回函數(shù)

@logging(level='INFO')
def say(something):
    print "say {}!".format(something)
            
          

內(nèi)置的裝飾器#

內(nèi)置的裝飾器和普通的裝飾器原理是一樣的,只不過(guò)返回的不是函數(shù),而是類(lèi)對(duì)象,所以更難理解一些

@property

@staticmethod,@classmethod


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論