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

Python裝飾器基礎(chǔ)概念與用法詳解

 更新時(shí)間:2018年12月22日 09:19:50   作者:KLeonard  
這篇文章主要介紹了Python裝飾器基礎(chǔ)概念與用法,結(jié)合實(shí)例形式詳細(xì)分析了Python裝飾器的概念、功能、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下

本文實(shí)例講述了Python裝飾器基礎(chǔ)概念與用法。分享給大家供大家參考,具體如下:

裝飾器基礎(chǔ)

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

什么是裝飾器

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

【1】函數(shù)裝飾器在函數(shù)定義的時(shí)候進(jìn)行名稱重綁定,提供一個(gè)邏輯層來(lái)管理函數(shù)和方法或隨后對(duì)它們的調(diào)用。
【2】類裝飾器在類定義的時(shí)候進(jìn)行名稱重綁定,提供一個(gè)邏輯層來(lái)管理類,或管理隨后調(diào)用它們所創(chuàng)建的實(shí)例。

簡(jiǎn)而言之,裝飾器提供了一種方法,在函數(shù)和類定義語(yǔ)句的末尾插入自動(dòng)運(yùn)行的代碼——對(duì)于函數(shù)裝飾器,在def的末尾;對(duì)于類裝飾器,在class的末尾。這樣的代碼可以扮演不同的角色。

裝飾器提供了一些和代碼維護(hù)性和審美相關(guān)的有點(diǎn)。此外,作為結(jié)構(gòu)化工具,裝飾器自然地促進(jìn)了代碼封裝,這減少了冗余性并使得未來(lái)變得更容易。

函數(shù)裝飾器

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

用法

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

在編碼上,函數(shù)裝飾器自動(dòng)將如下語(yǔ)法:

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

映射為這個(gè)對(duì)等形式:

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

這里的裝飾器是一個(gè)單參數(shù)的可調(diào)用對(duì)象,它返回與F具有相同數(shù)目的參數(shù)的一個(gè)可調(diào)用對(duì)象。

當(dāng)隨后調(diào)用F函數(shù)的時(shí)候,它自動(dòng)調(diào)用裝飾器所返回的對(duì)象。

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

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

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

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

實(shí)現(xiàn)

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

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

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

當(dāng)隨后調(diào)用名稱func的時(shí)候,它確實(shí)調(diào)用裝飾器所返回的包裝器函數(shù);隨后包裝器函數(shù)可能運(yùn)行最初的func,因?yàn)樗谝粋€(gè)封閉的作用域中仍然可以使用。

為了對(duì)類做同樣的事情,我們可以重載調(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)

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

如下反例:

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

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

這時(shí)候,嵌套函數(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ù)裝飾器使用相同的語(yǔ)法和非常相似的編碼方式。類裝飾器是管理類的一種方式,或者用管理或擴(kuò)展類所創(chuàng)建的實(shí)例的額外邏輯,來(lái)包裝實(shí)例構(gòu)建調(diào)用。

用法

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

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

等同于下面的語(yǔ)法:

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

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

實(shí)現(xiàn)

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

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)        # 等價(jià)于Wrapper(6,7)
print(x.attr)

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

就像函數(shù)裝飾器一樣,類裝飾器通??梢跃帉憺橐粋€(gè)創(chuàng)建并返回可調(diào)用對(duì)象的“工廠”函數(shù)。

裝飾器嵌套

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

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

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

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

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

裝飾器參數(shù)

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

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

自動(dòng)映射到其對(duì)等形式:

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

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

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

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

更多關(guān)于Python相關(guān)內(nèi)容可查看本站專題:《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python Socket編程技巧總結(jié)》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》及《Python入門與進(jìn)階經(jīng)典教程

希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • 關(guān)于Python中zipfile壓縮包模塊的使用

    關(guān)于Python中zipfile壓縮包模塊的使用

    這篇文章主要介紹了關(guān)于Python中zipfile壓縮包模塊的使用,zipfile?模塊提供了創(chuàng)建、讀取、寫入、添加及列出?ZIP?文件的工具,本文做一個(gè)簡(jiǎn)單的總結(jié),需要的朋友可以參考下
    2023-04-04
  • TensorFlow MNIST手寫數(shù)據(jù)集的實(shí)現(xiàn)方法

    TensorFlow MNIST手寫數(shù)據(jù)集的實(shí)現(xiàn)方法

    MNIST數(shù)據(jù)集中包含了各種各樣的手寫數(shù)字圖片,這篇文章主要介紹了TensorFlow MNIST手寫數(shù)據(jù)集的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2020-02-02
  • Python中Flask-RESTful編寫API接口(小白入門)

    Python中Flask-RESTful編寫API接口(小白入門)

    這篇文章主要介紹了Python中Flask-RESTful編寫API接口(小白入門),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • python聊天室(雖然很簡(jiǎn)潔,但是可以用)

    python聊天室(雖然很簡(jiǎn)潔,但是可以用)

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)多人聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 用Python實(shí)現(xiàn)BP神經(jīng)網(wǎng)絡(luò)(附代碼)

    用Python實(shí)現(xiàn)BP神經(jīng)網(wǎng)絡(luò)(附代碼)

    這篇文章主要介紹了用Python實(shí)現(xiàn)BP神經(jīng)網(wǎng)絡(luò)(附代碼),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • 淺談Python實(shí)現(xiàn)opencv之圖片色素的數(shù)值運(yùn)算和邏輯運(yùn)算

    淺談Python實(shí)現(xiàn)opencv之圖片色素的數(shù)值運(yùn)算和邏輯運(yùn)算

    今天帶大家來(lái)學(xué)習(xí)的是關(guān)于Python的相關(guān)知識(shí),文章圍繞著圖片色素的數(shù)值運(yùn)算和邏輯運(yùn)算展開,文中有非常詳細(xì)的的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • python獲取指定路徑下所有指定后綴文件的方法

    python獲取指定路徑下所有指定后綴文件的方法

    這篇文章主要介紹了python獲取指定路徑下所有指定后綴文件的方法,涉及Python針對(duì)文件與目錄操作的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • Python使用matplotlib創(chuàng)建Gif動(dòng)圖的思路

    Python使用matplotlib創(chuàng)建Gif動(dòng)圖的思路

    這篇文章主要介紹了Python使用matplotlib創(chuàng)建Gif動(dòng)圖,我們將討論matplotlib提供的名為“Animation”的動(dòng)畫庫(kù)之一,Python二維繪圖庫(kù)是Matplolib可以輕松創(chuàng)建繪圖、直方圖、條形圖、散點(diǎn)圖等,需要的朋友可以參考下
    2022-04-04
  • Python深度學(xué)習(xí)之Keras模型轉(zhuǎn)換成ONNX模型流程詳解

    Python深度學(xué)習(xí)之Keras模型轉(zhuǎn)換成ONNX模型流程詳解

    這篇文章主要介紹了Python深度學(xué)習(xí)之Keras模型轉(zhuǎn)換成ONNX模型流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-09-09
  • Django如何創(chuàng)作一個(gè)簡(jiǎn)單的最小程序

    Django如何創(chuàng)作一個(gè)簡(jiǎn)單的最小程序

    這篇文章主要介紹了Django如何創(chuàng)作一個(gè)簡(jiǎn)單的最小程序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評(píng)論

绍兴市| 三穗县| 西乡县| 松桃| 武清区| 怀来县| 白山市| 彩票| 吉木萨尔县| 九龙城区| 卓尼县| 兴义市| 罗山县| 高密市| 乌海市| 柞水县| 封丘县| 满城县| 万源市| 句容市| 堆龙德庆县| 兴义市| 富川| 沅陵县| 龙游县| 连城县| 安新县| 巢湖市| 彰化县| 永新县| 新宁县| 库车县| 庐江县| 乌兰浩特市| 灵石县| 远安县| 靖州| 樟树市| 林西县| 新宾| 海门市|