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

Python裝飾器使用你可能不知道的幾種姿勢

 更新時間:2019年10月25日 08:20:59   作者:麥麥麥造  
這篇文章主要給大家介紹了關(guān)于Python裝飾器使用你可能不知道的幾種姿勢,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

在Python中,裝飾器是一種十分強(qiáng)大并且好用的語法,一些重復(fù)的代碼使用裝飾器語法的話能夠使代碼更容易理解及閱讀。

因此在這里簡單總結(jié)了一下Python中裝飾器的幾種用法以及需要注意的事情。

一、在裝飾器中獲取被裝飾函數(shù)的參數(shù)

假設(shè)我們在開發(fā)web的時候,需要做反爬。要判斷接口的訪問來源我們就可以通過下面裝飾器的方法來實現(xiàn):

def mydecorator(func):
 def wrapped(*args, **kwargs):
  print("進(jìn)入裝飾器")
  if args[0]['header'] == 'spider':
   print("code: 400")
   return

  result = func(*args, **kwargs)
  return result

 return wrapped
@mydecorator
def request_page(request):
 print("一個訪問請求")
 print("返回了response")
if __name__ == '__main__':
 request = {
  'data': 100,
  'header': 'spider'
 }
 request_page(request)

在這個裝飾器中,我們在裝飾器中獲取了request中的header參數(shù),如果判斷訪問來源于爬蟲,那么便給它返回一個400。
使用裝飾器的寫法等同于下面不使用裝飾器的寫法

def mydecorator(*args, **kwargs):
 print("進(jìn)入函數(shù)")
 if args[0]['header'] == 'spider':
  print("code: 400")
  return False
 return True
def request_page(request):
 if not mydecorator(request):
  return
 print("訪問一個網(wǎng)頁")
 print("得到了response")
if __name__ == '__main__':
 request = {
  'data': 100,
  'header': 'spider'
 }
 request_page(request)

在只需要裝飾一個函數(shù)的時候后面一種寫法可能更優(yōu)于裝飾器的寫法,但是在需要裝飾很多個函數(shù)的時候,使用裝飾器明顯是更好的選擇。

二、在裝飾器獲取函數(shù)的返回值

有的時候我們需要對函數(shù)的返回值做出判斷,但又不想直接將判斷寫在函數(shù)里的時候,我們也可以使用裝飾器來實現(xiàn):

def mydecorator(func):
 def wrapped(*args, **kwargs):
  print("進(jìn)入裝飾器")
  result = func(*args, **kwargs)
  if result == 400:
   print("response is 400!")
   return False
  return True
 return wrapped

@mydecorator
def request_page():
 print("訪問一個網(wǎng)頁")
 print("得到了response")
 return 200

if __name__ == '__main__':
 print(request_page())

三、給裝飾器傳入?yún)?shù)

在實際應(yīng)用中,我們有時需要根據(jù)函數(shù)的執(zhí)行狀態(tài)來重復(fù)執(zhí)行。例如在編寫爬蟲的時候,可能由于網(wǎng)絡(luò)的原因會導(dǎo)致一些頁面訪問失敗,這時我們就需要根據(jù)爬蟲的返回結(jié)果進(jìn)行重復(fù)請求。

def retry(MAXRETRY=3):
 def decorator(func):
  def wrapped(*args, **kwargs):
   print("進(jìn)入裝飾器")

   result = 0
   retry = 1
   while result != 200 and retry <= MAXRETRY:
    result = func(*args, **kwargs)
    print("重試第%s次" % retry)
    retry += 1

   return result

  return wrapped

 return decorator
 
@retry(5)
def request_page():
 print("訪問一個網(wǎng)頁")
 print("得到了response")
 return 400

在這里我們假設(shè)訪問一個網(wǎng)頁得到400的時候便重新請求。我們在retry裝飾器里傳了一個5,這表示我們希望重試的最大次數(shù)為5次,如果不傳入這個值,那么它的默認(rèn)重試次數(shù)則為3次。

在熟悉了基本裝飾器的寫法后,傳參裝飾器的寫法也十分的好理解了。就是在外面多加了一層函數(shù),用于傳入?yún)?shù)。

四、裝飾器文檔的問題

我們都知道通過魔術(shù)方法__doc__可以獲取我們寫在代碼中的文檔,那么你是否知道使用裝飾器后,會造成被包裝函數(shù)的文檔被裝飾器的文檔覆蓋的問題呢。

def request_page():
 '''
 request_page 函數(shù)文檔
 :return:
 '''
 print("訪問一個網(wǎng)頁")
 print("得到了response")

if __name__ == '__main__':
 print(request_page.__doc__)

在上面對上面未使用裝飾的代碼使用__doc__方法的時候,我們得到的結(jié)果是:

In[3]: request_page.__doc__
Out[3]: '\n  request_page 函數(shù)文檔\n  :return:\n  '

這是我們理想中的結(jié)果!

但是當(dāng)我們將上述函數(shù)使用裝飾器裝飾后:

def decorator(func):
  def wrapped(*args, **kwargs):
    '''
    裝飾器文檔
    :param args:
    :param kwargs:
    :return:
    '''
    print("進(jìn)入裝飾器")
    result = func(*args, **kwargs)
    return result

  return wrapped


@decorator
def request_page():
  '''
  request_page 函數(shù)文檔
  :return:
  '''
  print("訪問一個網(wǎng)頁")
  print("得到了response")
  

我們再一次運(yùn)行__doc__魔術(shù)方法的時候,得到的結(jié)果卻是裝飾器的內(nèi)部文檔:

In[4]: request_page.__doc__
Out[4]: '\n    裝飾器文檔\n    :param args:\n    :param kwargs:\n    :return:\n    '
In[5]: request_page.__name__
Out[5]: 'wrapped'

這個問題會使得我們的調(diào)試變得困難,也會使許多自動文檔生成工具失去效果。

解決這個問題的最好辦法就是使用 functools包的wraps()模塊來將裝飾器進(jìn)行一個包裝。

from functools import wraps
def decorator(func):

  @wraps(func)
  def wrapped(*args, **kwargs):
    '''
    裝飾器
    :param args:
    :param kwargs:
    :return:
    '''
    print("進(jìn)入裝飾器")
    result = func(*args, **kwargs)
    return result
  return wrapped

@decorator
def request_page():
  '''
  request_page 函數(shù)文檔
  :return:
  '''
  print("訪問一個網(wǎng)頁")
  print("得到了response")
  

使用wraps將裝飾器裝飾后,這樣我們的函數(shù)便能夠保存它的一些重要數(shù)據(jù)了。

In[3]: request_page.__doc__
Out[3]: '\n  request_page 函數(shù)文檔\n  :return:\n  '
In[3]: request_page.__name__
Out[4]: 'request_page'

五、使用class的寫法來編寫裝飾器

雖然大多數(shù)的裝飾器都是通過函數(shù)的寫法來實現(xiàn)的,但同樣的可以通過類的寫法來實現(xiàn)裝飾器。

使用類的寫法,我們可以實現(xiàn)一些使用函數(shù)寫法不太好實現(xiàn)的需求。例如記錄一個函數(shù)執(zhí)行的次數(shù)

class Decorator():
  def __init__(self,func):
    print('類初始化')
    self.func = func
    self.count = 0
  def __call__(self, *args, **kwargs):
    print('進(jìn)入裝飾器')
    result = self.func(*args,**kwargs)
    self.count += 1

    return result
@Decorator
def request_page():
  '''
  request_page
  :return:
  '''
  print("訪問一個網(wǎng)頁")
  print("得到了response")

六、總結(jié)

裝飾器是Python里比較高級的一種語法,這里只是介紹了它的幾種使用技巧,以及需要注意的問題。借用金庸先生的話,“武功無高低,修為有深淺”。想要更加靈活的使用裝飾器,深入理解它的原理,我們在平時還是需要加強(qiáng)基本功的學(xué)習(xí)!

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。

相關(guān)文章

  • python中hashlib模塊用法示例

    python中hashlib模塊用法示例

    這篇文章主要介紹了python中hashlib模塊用法示例,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • 使用sklearn之LabelEncoder將Label標(biāo)準(zhǔn)化的方法

    使用sklearn之LabelEncoder將Label標(biāo)準(zhǔn)化的方法

    今天小編就為大家分享一篇使用sklearn之LabelEncoder將Label標(biāo)準(zhǔn)化的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • django 修改server端口號的方法

    django 修改server端口號的方法

    今天小編就為大家分享一篇django 修改server端口號的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Python中操作各種多媒體,視頻、音頻到圖片的代碼詳解

    Python中操作各種多媒體,視頻、音頻到圖片的代碼詳解

    這篇文章主要介紹了Python玩轉(zhuǎn)各種多媒體,視頻、音頻到圖片,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • python進(jìn)程間通信Queue工作過程詳解

    python進(jìn)程間通信Queue工作過程詳解

    這篇文章主要介紹了python進(jìn)程間通信Queue工作過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • 使用python搭建Django應(yīng)用程序步驟及版本沖突問題解決

    使用python搭建Django應(yīng)用程序步驟及版本沖突問題解決

    這篇文章主要介紹了使用python搭建Django應(yīng)用程序的步驟,最近還解決了因版本沖突出現(xiàn)的錯誤
    2013-11-11
  • python 通過麥克風(fēng)錄音 生成wav文件的方法

    python 通過麥克風(fēng)錄音 生成wav文件的方法

    今天小編就為大家分享一篇python 通過麥克風(fēng)錄音 生成wav文件的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python中數(shù)字(Number)數(shù)據(jù)類型常用操作

    Python中數(shù)字(Number)數(shù)據(jù)類型常用操作

    本文主要介紹了Python中數(shù)字(Number)數(shù)據(jù)類型常用操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Python入門教程(二十)Python的Lambda表達(dá)式

    Python入門教程(二十)Python的Lambda表達(dá)式

    這篇文章主要介紹了Python入門教程(二十)Python的Lambda表達(dá)式,lambda表達(dá)式是一行的函數(shù)。它們在其他語言中也被稱為匿名函數(shù),lambda表達(dá)式非常有用,可以讓代碼簡單,簡潔,需要的朋友可以參考下
    2023-04-04
  • pytest之a(chǎn)ssert斷言的具體使用

    pytest之a(chǎn)ssert斷言的具體使用

    這篇文章主要介紹了pytest之a(chǎn)ssert斷言的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04

最新評論