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

Python裝飾器基礎(chǔ)詳解

 更新時間:2016年03月09日 14:03:48   作者:GEJUNQIANG  
裝飾器(decorator)是一種高級Python語法。裝飾器可以對一個函數(shù)、方法或者類進行加工。接下來通過本文給大家介紹python裝飾器基礎(chǔ),對python裝飾器相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧

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

前面快速介紹了裝飾器的語法,在這里,我們將深入裝飾器內(nèi)部工作機制,更詳細更系統(tǒng)地介紹裝飾器的內(nèi)容,并學(xué)習(xí)自己編寫新的裝飾器的更多高級語法。

什么是裝飾器

裝飾是為函數(shù)和類指定管理代碼的一種方式。Python裝飾器以兩種形式呈現(xiàn):

【1】函數(shù)裝飾器在函數(shù)定義的時候進行名稱重綁定,提供一個邏輯層來管理函數(shù)和方法或隨后對它們的調(diào)用。

【2】類裝飾器在類定義的時候進行名稱重綁定,提供一個邏輯層來管理類,或管理隨后調(diào)用它們所創(chuàng)建的實例。

簡而言之,裝飾器提供了一種方法,在函數(shù)和類定義語句的末尾插入自動運行的代碼——對于函數(shù)裝飾器,在def的末尾;對于類裝飾器,在class的末尾。這樣的代碼可以扮演不同的角色。
裝飾器提供了一些和代碼維護性和審美相關(guān)的有點。此外,作為結(jié)構(gòu)化工具,裝飾器自然地促進了代碼封裝,這減少了冗余性并使得未來變得更容易。

函數(shù)裝飾器

通過在一個函數(shù)的def語句的末尾運行另一個函數(shù),把最初的函數(shù)名重新綁定到結(jié)果。

用法

裝飾器在緊挨著定義一個函數(shù)或方法的def語句之前的一行編寫,并且它由@符號以及緊隨其后的對于元函數(shù)的一個引用組成——這是管理另一個函數(shù)的一個函數(shù)(或其他可調(diào)用對象)。
在編碼上,函數(shù)裝飾器自動將如下語法:

@decorator 
def F(arg): 
... 
F(99)

映射為這個對等形式:

def F(arg): 
... 
F = decorator(F) 
F(99)

這里的裝飾器是一個單參數(shù)的可調(diào)用對象,它返回與F具有相同數(shù)目的參數(shù)的一個可調(diào)用對象。
當(dāng)隨后調(diào)用F函數(shù)的時候,它自動調(diào)用裝飾器所返回的對象。

換句話說,裝飾實際把如下的第一行映射為第二行(盡管裝飾器只在裝飾的時候運行一次)

fun(6,7) 
decorator(func)(6,7) 

這一自動名稱重綁定也解釋了之前介紹的靜態(tài)方法和property裝飾器語法的原因:

class C: 
@staticmethod 
def meth(...):... 
@property 
def name(self):...

實現(xiàn)

裝飾器自身是返回可調(diào)用對象的可調(diào)用對象。實際上,它可以是任意類型的可調(diào)用對象,并且返回任意類型的可調(diào)用對象:函數(shù)和類的任何組合都可以使用,盡管一些組合更適合于特定的背景。

有一種常用的編碼模式——裝飾器返回了一個包裝器,包裝器把最初的函數(shù)保持到一個封閉的作用域中:

def decorator(F): 
def wrapper(*args): 
# 使用 F 和 *args 
# 調(diào)用原來的F(*args) 
return wrapper 
@decorator 
def func(x,y): 
... 
func(6,7)

當(dāng)隨后調(diào)用名稱func的時候,它確實調(diào)用裝飾器所返回的包裝器函數(shù);隨后包裝器函數(shù)可能運行最初的func,因為它在一個封閉的作用域中仍然可以使用。

為了對類做同樣的事情,我們可以重載調(diào)用操作:

class decorator: 
def __init__(self,func): 
self.func = func 
def __call__(self,*args): 
# 使用self.func和args 
# self.func(*args)調(diào)用最初的func 
@decorator 
def func(x,y): 
... 
func(6,7)

但是,要注意的是,基于類的代碼中,它對于攔截簡單函數(shù)有效,但當(dāng)它應(yīng)用于類方法函數(shù)時,并不很有效:
如下反例:

class decorator: 
def __init__(self,func): 
self.func = func 
def __call__(self,*args): 
# 調(diào)用self.func(*args)失敗,因為C實例參數(shù)無法傳遞 
class C: 
@decorator 
def method(self,x,y): 
...

這時候裝飾的方法重綁定到一個類的方法上,而不是一個簡單的函數(shù),這一點帶來的問題是,當(dāng)裝飾器的方法__call__隨后運行的時候,其中的self接受裝飾器類實例,并且類C的實例不會包含到一個*args中。

這時候,嵌套函數(shù)的替代方法工作得更好:

def decorator: 
def warpper(*args): 
# ... 
return wrapper 
@decorator 
def func(x,y): 
... 
func(6,7) 
class C: 
@decorator 
def method(self,x,y): 
... 
x = C() 
x.method(6,7)

類裝飾器

類裝飾器與函數(shù)裝飾器使用相同的語法和非常相似的編碼方式。類裝飾器是管理類的一種方式,或者用管理或擴展類所創(chuàng)建的實例的額外邏輯,來包裝實例構(gòu)建調(diào)用。

用法

假設(shè)類裝飾器返回一個可調(diào)用對象的一個單參數(shù)的函數(shù),類裝飾器的語法為:

@decorator 
class C: 
... 
x = C(99)

等同于下面的語法:

class C: 
... 
C = decorator(C) 
x = C(99)

直接效果是隨后調(diào)用類名會創(chuàng)建一個實例,該實例會觸發(fā)裝飾器所返回的可調(diào)用對象,而不是調(diào)用最初的類自身。

實現(xiàn)

類裝飾器返回的可調(diào)用對象,通常創(chuàng)建并返回最初的類的一個新的實例,以某種方式來擴展對其接口的管理。例如,下面的實例插入一個對象來攔截一個類實例的未定義的屬性:

def decorator(cls): 
class Wrapper: 
def __init__(self,*args): 
self.wrapped = cls(*args) 
def __getattr__(self,name): 
return getattr(self.wrapped,name) 
return Wrapper 
@decorator 
class C: # C = decorator(C) 
def __init__(self,x,y): # Run by Wrapper.__init__ 
self.attr = 'spam' 
x = C(6,7) # 等價于Wrapper(6,7) 
print(x.attr)

在這個例子中,裝飾器把類的名稱重新綁定到另一個類,這個類在一個封閉的作用域中保持了最初的類。

就像函數(shù)裝飾器一樣,類裝飾器通常可以編寫為一個創(chuàng)建并返回可調(diào)用對象的“工廠”函數(shù)。

裝飾器嵌套

有時候,一個裝飾器不夠,裝飾器語法允許我們向一個裝飾器的函數(shù)或方法添加包裝器邏輯的多個層。這種形式的裝飾器的語法為:

@A 
@B 
@C 
def f(...): 
...

如下這樣轉(zhuǎn)換:

def f(...): 
... 
f = A(B(C(f))) 

這里,最初的函數(shù)通過3個不同的裝飾器傳遞,每個裝飾器處理前一個結(jié)果。

裝飾器參數(shù)

函數(shù)裝飾器和類裝飾器都能接受參數(shù),如下:

@decorator(A,B) 
def F(arg): 
... 
F(99)

自動映射到其對等形式:

def F(arg): 
... 
F = decorator(A,B)(F) 
F(99)

裝飾器參數(shù)在裝飾之前就解析了,并且它們通常用來保持狀態(tài)信息供隨后的調(diào)用使用。例如,這個例子中的裝飾器函數(shù),可能采用如下形式:

def decorator(A,B): 
# 保存或使用A和B 
def actualDecorator(F): 
# 保存或使用函數(shù) F 
# 返回一個可調(diào)用對象 
return callable 
return actualDecorator

以上,這是裝飾器的基礎(chǔ)知識,接下來將學(xué)習(xí)編寫自己的裝飾器。

相關(guān)文章

  • Python使用functools模塊中的partial函數(shù)生成偏函數(shù)

    Python使用functools模塊中的partial函數(shù)生成偏函數(shù)

    所謂偏函數(shù)即是規(guī)定了固定參數(shù)的函數(shù),在函數(shù)式編程中我們經(jīng)??梢杂玫?這里我們就來看一下Python使用functools模塊中的partial函數(shù)生成偏函數(shù)的方法
    2016-07-07
  • python實現(xiàn)一組典型數(shù)據(jù)格式轉(zhuǎn)換

    python實現(xiàn)一組典型數(shù)據(jù)格式轉(zhuǎn)換

    這篇文章主要為大家詳細介紹了python實現(xiàn)一組典型數(shù)據(jù)格式轉(zhuǎn)換,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • python requests爬取高德地圖數(shù)據(jù)的實例

    python requests爬取高德地圖數(shù)據(jù)的實例

    今天小編就為大家分享一篇python requests爬取高德地圖數(shù)據(jù)的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • Python面向?qū)ο笾惖亩x與繼承用法示例

    Python面向?qū)ο笾惖亩x與繼承用法示例

    這篇文章主要介紹了Python面向?qū)ο笾惖亩x與繼承用法,結(jié)合實例形式分析了Python類的定義、實例化、繼承等基本操作技巧,需要的朋友可以參考下
    2019-01-01
  • 基于python 字符編碼的理解

    基于python 字符編碼的理解

    下面小編就為大家?guī)硪黄趐ython 字符編碼的理解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 用python畫圣誕樹三種代碼示例介紹

    用python畫圣誕樹三種代碼示例介紹

    大家好,本篇文章主要講的是用python畫圣誕樹三種代碼示例介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Httprunner簡介、安裝及基本使用教程

    Httprunner簡介、安裝及基本使用教程

    httprunner是一款面向 HTTP(S) 協(xié)議的通用測試框架。只需編寫維護一份 YAML/JSON 腳本,即可實現(xiàn)自動化測試、性能測試、線上監(jiān)控、持續(xù)集成等多種測試需求,本文給大家介紹Httprunner安裝使用教程,感興趣的朋友一起看看吧
    2022-02-02
  • Python讀取xlsx文件報錯:xlrd.biffh.XLRDError:?Excel?xlsx?file;not?supported問題解決

    Python讀取xlsx文件報錯:xlrd.biffh.XLRDError:?Excel?xlsx?file;no

    這篇文章主要給大家介紹了關(guān)于Python庫xlrd中的xlrd.open_workbook()函數(shù)讀取xlsx文件報錯:xlrd.biffh.XLRDError:?Excel?xlsx?file;not?supported問題解決的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • 詳解【python】str與json類型轉(zhuǎn)換

    詳解【python】str與json類型轉(zhuǎn)換

    這篇文章主要介紹了【python】str與json類型轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • python sorted函數(shù)的小練習(xí)及解答

    python sorted函數(shù)的小練習(xí)及解答

    這篇文章主要介紹了python sorted函數(shù)的小練習(xí)及解答,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-09-09

最新評論