最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python深入學(xué)習(xí)之裝飾器

 更新時(shí)間:2014年08月31日 15:08:53   投稿:junjie  
這篇文章主要介紹了Python深入學(xué)習(xí)之裝飾器,裝飾器(decorator)是一種高級(jí)Python語法,本文全面介紹了Python中的裝飾器,需要的朋友可以參考下

裝飾器(decorator)是一種高級(jí)Python語法。裝飾器可以對(duì)一個(gè)函數(shù)、方法或者類進(jìn)行加工。在Python中,我們有多種方法對(duì)函數(shù)和類進(jìn)行加工,比如在Python閉包中,我們見到函數(shù)對(duì)象作為某一個(gè)函數(shù)的返回結(jié)果。相對(duì)于其它方式,裝飾器語法簡(jiǎn)單,代碼可讀性高。因此,裝飾器在Python項(xiàng)目中有廣泛的應(yīng)用。

裝飾器最早在Python 2.5中出現(xiàn),它最初被用于加工函數(shù)和方法這樣的可調(diào)用對(duì)象(callable object,這樣的對(duì)象定義有__call__方法)。在Python 2.6以及之后的Python版本中,裝飾器被進(jìn)一步用于加工類。

裝飾函數(shù)和方法

我們先定義兩個(gè)簡(jiǎn)單的數(shù)學(xué)函數(shù),一個(gè)用來計(jì)算平方和,一個(gè)用來計(jì)算平方差:

復(fù)制代碼 代碼如下:

# get square sum
def square_sum(a, b):
    return a**2 + b**2

# get square diff
def square_diff(a, b):
    return a**2 - b**2

print(square_sum(3, 4))
print(square_diff(3, 4))

在擁有了基本的數(shù)學(xué)功能之后,我們可能想為函數(shù)增加其它的功能,比如打印輸入。我們可以改寫函數(shù)來實(shí)現(xiàn)這一點(diǎn):

復(fù)制代碼 代碼如下:

# modify: print input

# get square sum
def square_sum(a, b):
    print("intput:", a, b)
    return a**2 + b**2

# get square diff
def square_diff(a, b):
    print("input", a, b)
    return a**2 - b**2

print(square_sum(3, 4))
print(square_diff(3, 4))

我們修改了函數(shù)的定義,為函數(shù)增加了功能。

現(xiàn)在,我們使用裝飾器來實(shí)現(xiàn)上述修改:

復(fù)制代碼 代碼如下:

def decorator(F):
    def new_F(a, b):
        print("input", a, b)
        return F(a, b)
    return new_F

# get square sum
@decorator
def square_sum(a, b):
    return a**2 + b**2

# get square diff
@decorator
def square_diff(a, b):
    return a**2 - b**2

print(square_sum(3, 4))
print(square_diff(3, 4))


裝飾器可以用def的形式定義,如上面代碼中的decorator。裝飾器接收一個(gè)可調(diào)用對(duì)象作為輸入?yún)?shù),并返回一個(gè)新的可調(diào)用對(duì)象。裝飾器新建了一個(gè)可調(diào)用對(duì)象,也就是上面的new_F。new_F中,我們?cè)黾恿舜蛴〉墓δ?,并通過調(diào)用F(a, b)來實(shí)現(xiàn)原有函數(shù)的功能。

定義好裝飾器后,我們就可以通過@語法使用了。在函數(shù)square_sum和square_diff定義之前調(diào)用@decorator,我們實(shí)際上將square_sum或square_diff傳遞給decorator,并將decorator返回的新的可調(diào)用對(duì)象賦給原來的函數(shù)名(square_sum或square_diff)。 所以,當(dāng)我們調(diào)用square_sum(3, 4)的時(shí)候,就相當(dāng)于:

復(fù)制代碼 代碼如下:

square_sum = decorator(square_sum)
square_sum(3, 4)

我們知道,Python中的變量名和對(duì)象是分離的。變量名可以指向任意一個(gè)對(duì)象。從本質(zhì)上,裝飾器起到的就是這樣一個(gè)重新指向變量名的作用(name binding),讓同一個(gè)變量名指向一個(gè)新返回的可調(diào)用對(duì)象,從而達(dá)到修改可調(diào)用對(duì)象的目的。

與加工函數(shù)類似,我們可以使用裝飾器加工類的方法。

如果我們有其他的類似函數(shù),我們可以繼續(xù)調(diào)用decorator來修飾函數(shù),而不用重復(fù)修改函數(shù)或者增加新的封裝。這樣,我們就提高了程序的可重復(fù)利用性,并增加了程序的可讀性。

含參的裝飾器

在上面的裝飾器調(diào)用中,比如@decorator,該裝飾器默認(rèn)它后面的函數(shù)是唯一的參數(shù)。裝飾器的語法允許我們調(diào)用decorator時(shí),提供其它參數(shù),比如@decorator(a)。這樣,就為裝飾器的編寫和使用提供了更大的靈活性。

復(fù)制代碼 代碼如下:

# a new wrapper layer
def pre_str(pre=''):
    # old decorator
    def decorator(F):
        def new_F(a, b):
            print(pre + "input", a, b)
            return F(a, b)
        return new_F
    return decorator

# get square sum
@pre_str('^_^')
def square_sum(a, b):
    return a**2 + b**2

# get square diff
@pre_str('T_T')
def square_diff(a, b):
    return a**2 - b**2

print(square_sum(3, 4))
print(square_diff(3, 4))


上面的pre_str是允許參數(shù)的裝飾器。它實(shí)際上是對(duì)原有裝飾器的一個(gè)函數(shù)封裝,并返回一個(gè)裝飾器。我們可以將它理解為一個(gè)含有環(huán)境參量的閉包。當(dāng)我們使用@pre_str('^_^')調(diào)用的時(shí)候,Python能夠發(fā)現(xiàn)這一層的封裝,并把參數(shù)傳遞到裝飾器的環(huán)境中。該調(diào)用相當(dāng)于:
復(fù)制代碼 代碼如下:

square_sum = pre_str('^_^') (square_sum)

裝飾類

在上面的例子中,裝飾器接收一個(gè)函數(shù),并返回一個(gè)函數(shù),從而起到加工函數(shù)的效果。在Python 2.6以后,裝飾器被拓展到類。一個(gè)裝飾器可以接收一個(gè)類,并返回一個(gè)類,從而起到加工類的效果。

復(fù)制代碼 代碼如下:

def decorator(aClass):
    class newClass:
        def __init__(self, age):
            self.total_display   = 0
            self.wrapped         = aClass(age)
        def display(self):
            self.total_display += 1
            print("total display", self.total_display)
            self.wrapped.display()
    return newClass

@decorator
class Bird:
    def __init__(self, age):
        self.age = age
    def display(self):
        print("My age is",self.age)

eagleLord = Bird(5)
for i in range(3):
    eagleLord.display()


在decorator中,我們返回了一個(gè)新類newClass。在新類中,我們記錄了原來類生成的對(duì)象(self.wrapped),并附加了新的屬性total_display,用于記錄調(diào)用display的次數(shù)。我們也同時(shí)更改了display方法。

通過修改,我們的Bird類可以顯示調(diào)用display的次數(shù)了。

總結(jié)

裝飾器的核心作用是name binding。這種語法是Python多編程范式的又一個(gè)體現(xiàn)。大部分Python用戶都不怎么需要定義裝飾器,但有可能會(huì)使用裝飾器。鑒于裝飾器在Python項(xiàng)目中的廣泛使用,了解這一語法是非常有益的。

相關(guān)文章

  • python中的生成器實(shí)現(xiàn)周期性報(bào)文發(fā)送功能

    python中的生成器實(shí)現(xiàn)周期性報(bào)文發(fā)送功能

    本文主要介紹了python中的生成器實(shí)現(xiàn)周期性報(bào)文發(fā)送功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Python變量的定義和運(yùn)算符的使用

    Python變量的定義和運(yùn)算符的使用

    這篇文章主要介紹了Python變量的定義和運(yùn)算符的使用,Python和C/Java不同,在定義變量的時(shí)候不需要顯示的指定變量的類型,在賦值的時(shí)候自動(dòng)就會(huì)確定類型,需要的朋友可以參考下
    2023-05-05
  • python文件讀寫并使用mysql批量插入示例分享(python操作mysql)

    python文件讀寫并使用mysql批量插入示例分享(python操作mysql)

    這篇文章主要介紹了python文件讀寫并使用mysql批量插入示例,可以學(xué)習(xí)到python操作mysql數(shù)據(jù)庫(kù)的方法,需要的朋友可以參考下
    2014-02-02
  • python基于numpy的線性回歸

    python基于numpy的線性回歸

    這篇文章主要為大家詳細(xì)介紹了python基于numpy的線性回歸,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Pycharm快速安裝OpenCV的詳細(xì)操作步驟

    Pycharm快速安裝OpenCV的詳細(xì)操作步驟

    Pycharm中使用OpenCV,其實(shí)也就是用Python語言調(diào)用OpenCV,下面這篇文章主要給大家介紹了關(guān)于Pycharm快速安裝OpenCV的詳細(xì)操作步驟,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Python多線程同步Lock、RLock、Semaphore、Event實(shí)例

    Python多線程同步Lock、RLock、Semaphore、Event實(shí)例

    這篇文章主要介紹了Python多線程同步Lock、RLock、Semaphore、Event實(shí)例,Lock & RLock 用來確保多線程多共享資源的訪問,Semaphore用來確保一定資源多線程訪問時(shí)的上限,Event是最簡(jiǎn)單的線程間通信的方式,需要的朋友可以參考下
    2014-11-11
  • 簡(jiǎn)單了解Python matplotlib線的屬性

    簡(jiǎn)單了解Python matplotlib線的屬性

    這篇文章主要介紹了簡(jiǎn)單了解Python matplotlib線的屬性,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-06-06
  • python實(shí)現(xiàn)圖像的隨機(jī)增強(qiáng)變換

    python實(shí)現(xiàn)圖像的隨機(jī)增強(qiáng)變換

    這篇文章主要為大家介紹了如何利用pythons制作一個(gè)小工具工具,可以實(shí)現(xiàn)圖像的隨機(jī)增強(qiáng)變換,可用于分類訓(xùn)練數(shù)據(jù)的增強(qiáng),有需要的可以參考下
    2024-11-11
  • python編寫學(xué)生成績(jī)管理系統(tǒng)的邏輯結(jié)構(gòu)及功能實(shí)現(xiàn)

    python編寫學(xué)生成績(jī)管理系統(tǒng)的邏輯結(jié)構(gòu)及功能實(shí)現(xiàn)

    這篇文章主要為大家介紹了python編寫學(xué)生成績(jī)管理系統(tǒng)實(shí)現(xiàn)八個(gè)功能示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • 20行代碼教你用python給證件照換底色的方法示例

    20行代碼教你用python給證件照換底色的方法示例

    這篇文章主要介紹了20行代碼教你用python給證件照換底色的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02

最新評(píng)論

天水市| 息烽县| 玛纳斯县| 旬阳县| 穆棱市| 黔西县| 延边| 达日县| 阜城县| 揭东县| 辽中县| 息烽县| 右玉县| 锡林郭勒盟| 湖州市| 海原县| 平潭县| 白朗县| 吴川市| 汉寿县| 永川市| 增城市| 剑河县| 新闻| 青神县| 武冈市| 淮南市| 抚州市| 封开县| 十堰市| 马山县| 鹤岗市| 泾川县| 清镇市| 迁西县| 盐边县| 东至县| 沙田区| 沂水县| 湄潭县| 怀来县|