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

Python編程中裝飾器的使用示例解析

 更新時(shí)間:2016年06月20日 16:43:12   作者:JeffLi1993  
這篇文章主要介紹了Python編程中裝飾器的使用示例解析,包括裝飾函數(shù)和方法,含參的裝飾器以及裝飾類(lèi)這三個(gè)方面,需要的朋友可以參考下

裝飾函數(shù)和方法

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

# 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ù)增加其它的功能,比如打印輸入。我們可以改寫(xiě)函數(shù)來(lái)實(shí)現(xiàn)這一點(diǎn):

# 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)在,我們使用裝飾器來(lái)實(shí)現(xiàn)上述修改:

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è)黾恿舜蛴〉墓δ?,并通過(guò)調(diào)用F(a, b)來(lái)實(shí)現(xiàn)原有函數(shù)的功能。

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

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ù)類(lèi)似,我們可以使用裝飾器加工類(lèi)的方法。

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

含參的裝飾器

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

# 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)于:

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

裝飾類(lèi)

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

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è)新類(lèi)newClass。在新類(lèi)中,我們記錄了原來(lái)類(lèi)生成的對(duì)象(self.wrapped),并附加了新的屬性total_display,用于記錄調(diào)用display的次數(shù)。我們也同時(shí)更改了display方法。

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

相關(guān)文章

  • Python 使用dict實(shí)現(xiàn)switch的操作

    Python 使用dict實(shí)現(xiàn)switch的操作

    這篇文章主要介紹了Python 使用dict實(shí)現(xiàn)switch的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • Scrapy的簡(jiǎn)單使用教程

    Scrapy的簡(jiǎn)單使用教程

    Scrapy,Python開(kāi)發(fā)的一個(gè)快速,高層次的屏幕抓取和web抓取框架,用于抓取web站點(diǎn)并從頁(yè)面中提取結(jié)構(gòu)化的數(shù)據(jù)。Scrapy用途廣泛,可以用于數(shù)據(jù)挖掘、監(jiān)測(cè)和自動(dòng)化測(cè)試。
    2017-10-10
  • Python基于最小二乘法實(shí)現(xiàn)曲線(xiàn)擬合示例

    Python基于最小二乘法實(shí)現(xiàn)曲線(xiàn)擬合示例

    這篇文章主要介紹了Python基于最小二乘法實(shí)現(xiàn)曲線(xiàn)擬合,涉及Python基于numpy及scipy庫(kù)進(jìn)行曲線(xiàn)擬合操作相關(guān)運(yùn)算技巧,需要的朋友可以參考下
    2018-06-06
  • Python編程在flask中模擬進(jìn)行Restful的CRUD操作

    Python編程在flask中模擬進(jìn)行Restful的CRUD操作

    今天小編就為大家分享一篇關(guān)于Python編程在flask中模擬進(jìn)行Restful的CRUD操作,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • 解決Python獲取字典dict中不存在的值時(shí)出錯(cuò)問(wèn)題

    解決Python獲取字典dict中不存在的值時(shí)出錯(cuò)問(wèn)題

    今天小編就為大家分享一篇解決Python獲取字典dict中不存在的值時(shí)出錯(cuò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • PyQt5每天必學(xué)之拖放事件

    PyQt5每天必學(xué)之拖放事件

    這篇文章主要為大家詳細(xì)介紹了PyQt5每天必學(xué)之拖放事件的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • tensorflow: 查看 tensor詳細(xì)數(shù)值方法

    tensorflow: 查看 tensor詳細(xì)數(shù)值方法

    今天小編就為大家分享一篇tensorflow: 查看 tensor詳細(xì)數(shù)值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • Python利用蒙特卡羅模擬期權(quán)定價(jià)

    Python利用蒙特卡羅模擬期權(quán)定價(jià)

    期權(quán)是一種合約,它賦予買(mǎi)方在未來(lái)某個(gè)時(shí)間點(diǎn)以特定價(jià)格買(mǎi)賣(mài)資產(chǎn)的權(quán)利。本文將利用蒙特卡羅模擬期權(quán)定價(jià),感興趣的小伙伴可以了解一下
    2022-04-04
  • Python入門(mén)教程(三十九)Python的NumPy安裝與入門(mén)

    Python入門(mén)教程(三十九)Python的NumPy安裝與入門(mén)

    這篇文章主要介紹了Python入門(mén)教程(三十九)Python的NumPy安裝與入門(mén),NumPy 是一個(gè)Python包,它是一個(gè)由多維數(shù)組對(duì)象和用于處理數(shù)組的例程集合組成的庫(kù),,需要的朋友可以參考下
    2023-05-05
  • Python文件讀寫(xiě)保存操作的示例代碼

    Python文件讀寫(xiě)保存操作的示例代碼

    這篇文章主要介紹了Python文件讀寫(xiě)保存操作的示例代碼,實(shí)現(xiàn)了單個(gè)文件和多文件的讀寫(xiě)保存操作,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09

最新評(píng)論