欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中的閉包與裝飾器的用法詳解

 更新時(shí)間:2023年07月29日 10:09:54   作者:夏末ya  
這篇文章主要介紹了Python中的閉包與裝飾器的用法詳解,裝飾器本質(zhì)上是一個(gè)Python函數(shù),它可以讓其他函數(shù)在不需要做任何代碼變動(dòng)的前提下增加額外功能,裝飾器的返回值也是一個(gè)函數(shù)對(duì)象,需要的朋友可以參考下

閉包

Python函數(shù)是支持嵌套的。如果在一個(gè)內(nèi)部函數(shù)中對(duì)外部函數(shù)作用域(非全局作用域)的變量進(jìn)行引用,那么內(nèi)部函數(shù)就會(huì)被稱(chēng)為閉包。

閉包需要滿足如下3個(gè)條件:

1.存在于兩個(gè)嵌套關(guān)系的函數(shù)中,并且閉包是內(nèi)部函數(shù);

2.內(nèi)部函數(shù)引用了外部函數(shù)的變量(自由變量);

3.外部函數(shù)會(huì)把內(nèi)部函數(shù)的函數(shù)名稱(chēng)返回。

示例:

在這里插入圖片描述

裝飾器

1、裝飾器本質(zhì)上是一個(gè)Python函數(shù),它可以讓其他函數(shù)在不需要做任何代碼變動(dòng)的前提下增加額外功能,裝飾器的返回值也是一個(gè)函數(shù)對(duì)象。它經(jīng)常用于有切面需求的場(chǎng)景,比如:插入日志、性能測(cè)試、事務(wù)處理、緩存、權(quán)限校驗(yàn)等場(chǎng)景。裝飾器是解決這類(lèi)問(wèn)題的絕佳設(shè)計(jì),有了裝飾器,我們就可以抽離出大量與函數(shù)功能本身無(wú)關(guān)的雷同代碼并繼續(xù)重用。

2、裝飾器是一個(gè)函數(shù),它需要接收一個(gè)參數(shù),該參數(shù)表示被修飾的函數(shù)。

例如,有如下一個(gè)裝飾器函數(shù):

def w1(func):
   print(‘正在裝飾')
    def inner():
        print(‘正在驗(yàn)證權(quán)限')
        return inner()
  • 裝飾器是個(gè)嵌套函數(shù)
  • 內(nèi)部函數(shù)是一個(gè)閉包。
  • 外部函數(shù)接收的是被修飾的函數(shù)(func)

3、通過(guò)在函數(shù)定義的前面添加@符號(hào)和裝飾器名,實(shí)現(xiàn)裝飾器對(duì)函數(shù)的包裝。

給f1函數(shù)加上裝飾器,示例如下:

@w1
def f1():
    print('f1')

此時(shí),程序會(huì)自動(dòng)編譯生成調(diào)用裝飾器函數(shù)的代碼,等價(jià)于: f1 = w1(f1)

多個(gè)裝飾器

多個(gè)裝飾器應(yīng)用在一個(gè)函數(shù)上,調(diào)用順序是從下至上。

@w1
@w2
def f1():
        print(‘---f1---')

執(zhí)行順序:先執(zhí)行@w2,后執(zhí)行@w1

帶參數(shù)的裝飾器

假設(shè)我們前文的裝飾器需要完成的功能不僅僅是能在進(jìn)入某個(gè)函數(shù)后打出log信息,而且還需指定log的級(jí)別,那么裝飾器就會(huì)是這樣的。

  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")
  • 當(dāng)帶參數(shù)的裝飾器被打在某個(gè)函數(shù)上時(shí),比如@logging(level=‘DEBUG’),它其實(shí)是一個(gè)函數(shù),會(huì)馬上被執(zhí)行,只要這個(gè)它返回的結(jié)果是一個(gè)裝飾器時(shí),那就沒(méi)問(wèn)題。

基于類(lèi)實(shí)現(xiàn)的裝飾器

裝飾器函數(shù)其實(shí)是這樣一個(gè)接口約束,它必須接受一個(gè)callable對(duì)象作為參數(shù),然后返回一個(gè)callable對(duì)象。

在Python中一般callable對(duì)象都是函數(shù),但也有例外。只要某個(gè)對(duì)象重載了__call__()方法,那么這個(gè)對(duì)象就是callable的。

class Test():
    def __call__(self):
        print 'call me!'
t = Test()
t()  # call me

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

重載這些魔法方法一般會(huì)改變對(duì)象的內(nèi)部行為。上面這個(gè)例子就讓一個(gè)類(lèi)對(duì)象擁有了被調(diào)用的行為。

回到裝飾器上的概念上來(lái),裝飾器要求接受一個(gè)callable對(duì)象,并返回一個(gè)callable對(duì)象(不太嚴(yán)謹(jǐn),詳見(jiàn)后文)。

那么用類(lèi)來(lái)實(shí)現(xiàn)也是也可以的。我們可以讓類(lèi)的構(gòu)造函數(shù)__init__()接受一個(gè)函數(shù),然后重載__call__()并返回一個(gè)函數(shù),也可以達(dá)到裝飾器函數(shù)的效果。

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)

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

如果需要通過(guò)類(lèi)形式實(shí)現(xiàn)帶參數(shù)的裝飾器,那么會(huì)比前面的例子稍微復(fù)雜一點(diǎn)。那么在構(gòu)造函數(shù)里接受的就不是一個(gè)函數(shù),而是傳入的參數(shù)。通過(guò)類(lèi)把這些參數(shù)保存起來(lái)。然后在重載__call__方法是就需要接受一個(gè)函數(shù)并返回一個(gè)函數(shù)。

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ì)象。 在了解這個(gè)裝飾器前,你需要知道在不使用裝飾器怎么寫(xiě)一個(gè)屬性。

def getx(self):
    return self._x
def setx(self, value):
    self._x = value
def delx(self):
   del self._x
# create a property
x = property(getx, setx, delx, "I am doc for x property")

以上就是一個(gè)Python屬性的標(biāo)準(zhǔn)寫(xiě)法,其實(shí)和Java挺像的,但是太羅嗦。有了@語(yǔ)法糖,能達(dá)到一樣的效果但看起來(lái)更簡(jiǎn)單。

@property
def x(self): ...
# 等同于
def x(self): ...
x = property(x)

帶有返回值的裝飾器

  def func(functionName):
        def func_in():  	  
        	return functionName()    
        return func_in 
     @func def test():
        return ‘itheima'

到此這篇關(guān)于Python中的閉包與裝飾器的用法詳解的文章就介紹到這了,更多相關(guān)Python裝飾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • PyQt與pycharm的結(jié)合使用教程

    PyQt與pycharm的結(jié)合使用教程

    這篇文章主要介紹了PyQt的使用與pycharm的結(jié)合,主要包括環(huán)境安裝,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • 深入理解python中sort()與sorted()的區(qū)別

    深入理解python中sort()與sorted()的區(qū)別

    Python list內(nèi)置sort()方法用來(lái)排序,也可以用python內(nèi)置的全局sorted()方法來(lái)對(duì)可迭代的序列排序生成新的序列。這篇文章主要介紹了python中sort()與sorted()的區(qū)別,需要的朋友可以參考下
    2018-08-08
  • 關(guān)于python3安裝pip及requests庫(kù)的導(dǎo)入問(wèn)題

    關(guān)于python3安裝pip及requests庫(kù)的導(dǎo)入問(wèn)題

    小編最近快畢業(yè)了,閑著無(wú)事學(xué)習(xí)下python的內(nèi)容在學(xué)習(xí)到requsets庫(kù)的導(dǎo)入問(wèn)題時(shí)遇到一些問(wèn)題,通過(guò)查找相關(guān)資料問(wèn)題順利解決,今天小編把問(wèn)題解決思路及注意事項(xiàng)分享給大家供大家參考學(xué)習(xí)
    2021-05-05
  • 使用grpc實(shí)現(xiàn)golang后端和python服務(wù)間通信

    使用grpc實(shí)現(xiàn)golang后端和python服務(wù)間通信

    gRPC是Google 開(kāi)發(fā)的高性能、開(kāi)源的遠(yuǎn)程過(guò)程調(diào)用(RPC)框架,本文主要為大家詳細(xì)介紹了如何使用grpc實(shí)現(xiàn)golang后端和python服務(wù)間通信,感興趣的可以了解下
    2024-03-03
  • Python+turtle繪制對(duì)稱(chēng)圖形的示例代碼

    Python+turtle繪制對(duì)稱(chēng)圖形的示例代碼

    這篇文章主要是帶大家寫(xiě)一個(gè)利用Turtle庫(kù)繪制一些有趣的對(duì)稱(chēng)圖形,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定幫助,感興趣的可以了解一下
    2022-07-07
  • 最新評(píng)論