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

python 自定義裝飾器實例詳解

 更新時間:2019年07月20日 16:02:47   作者:Panda_Boy_yi  
這篇文章主要介紹了python 自定義裝飾器,結(jié)合實例形式分析了Python自定義裝飾器的功能、原理、用法及相關(guān)操作注意事項,需要的朋友可以參考下

本文實例講述了python 自定義裝飾器。分享給大家供大家參考,具體如下:

先看一個例子

def deco(func):
  print("before myfunc() called.")
  func()
  print("after myfunc() called.")
  return func
@deco
def myfunc():
  print("myfunc() called.")
# myfunc = deco(myfunc) # 與上面的@deco等價
myfunc()
print("***********")
myfunc()

會發(fā)現(xiàn),輸出為

before myfunc() called.
myfunc() called.
after myfunc() called.
myfunc() called.
***********
myfunc() called.

這就是說,裝飾器里面的東西只調(diào)用了一次,為什么呢?

是因為,在myfunc()函數(shù)的定義前面加一句@deco,本質(zhì)上完全等價于在出現(xiàn)def myfunc()后,先將下面所有內(nèi)容的首地址傳遞給func,然后緊接著加上一句 myfunc = deco(myfunc)。執(zhí)行這句話,表示func代表了本來定義的myfunc()的函數(shù)體,同時函數(shù)myfunc()的地址傳遞給deco()函數(shù),即 myfunc -> func,這里就相當于myfunc的值與func的值完全相同了。然后執(zhí)行裝飾器里面的內(nèi)容,最后返回給func,傳遞給myfunc。接下來在調(diào)用myfunc()的時候,打印輸出“myfunc() called”。第二次調(diào)用myfunc()函數(shù)的時候,依然只打印輸出“myfunc() called”。為什么第二次沒有執(zhí)行裝飾器里面的內(nèi)容呢?是因為,myfunc = deco(myfunc)這句話只執(zhí)行了一次,而這句話,才是真正執(zhí)行裝飾器里面的內(nèi)容的話。

上面的代碼表示,裝飾器相當于只對第一次調(diào)用他的函數(shù)進行了裝飾,那么,怎么對每次調(diào)用的函數(shù)都裝飾呢?接著看

def deco(func):
  def wrapper(*args, **kwargs): # *args, **kwargs用于接收func的參數(shù)
    print("before myfunc() called.")
    func(*args, **kwargs)
    print("after myfunc() called.")
  return wrapper
@deco
def myfunc(a, b):
  print(a+b)
# myfunc = deco(myfunc) # 與上面的@deco等價
myfunc(1, 2)
print("***********")
myfunc(3, 4)

該代碼輸出結(jié)果為

before myfunc() called.
3
after myfunc() called.
***********
before myfunc() called.
7
after myfunc() called.

我們說了,在myfunc()函數(shù)的定義前面加一句@deco,本質(zhì)上完全等價于在出現(xiàn)def?myfunc()后,先將下面所有內(nèi)容的首地址傳遞給func,然后緊接著加上一句 myfunc = deco(myfunc)。執(zhí)行myfunc(1, 2)命令的時候,myfunc函數(shù)體的地址早已經(jīng)傳遞給了deco()函數(shù),返回的是wrapper。這是myfunc所代表的地址不再是原來的myfunc的地址,而是wrapper函數(shù)的地址。所以,以后凡是出現(xiàn)myfunc()的地方,都是在調(diào)用wrapper()函數(shù)。即myfunc(1, 2)就是wrapper(1, 2),所以每次調(diào)用myfunc()時候,裝飾器里面的內(nèi)容都會被執(zhí)行了。而wrapper()函數(shù)體里面的func,就代表了原來myfunc()的函數(shù)體。

怎么進一步理解“在出現(xiàn)def?myfunc()后,先將下面所有內(nèi)容的首地址傳遞給func”這句話呢?看:

def deco(func):
  def wrapper(*args, **kwargs): # *args, **kwargs用于接收func的參數(shù)
    print("wrapper的地址:", wrapper)
    func(*args, **kwargs)
    print("func的地址:", func)
  return wrapper
@deco
def myfunc(a, b):
  print("myfunc的地址:",myfunc)
  print(a+b)
# myfunc = deco(myfunc) # 與上面的@deco等價
myfunc(1, 2)
print("***********")
print("修改后myfunc的地址:",myfunc)

運行結(jié)果:

wrapper的地址: <function deco.<locals>.wrapper at 0x0000023AA9FF58C8>
myfunc的地址: <function deco.<locals>.wrapper at 0x0000023AA9FF58C8>
3
func的地址: <function myfunc at 0x0000023AA9FF5840>
***********
修改后myfunc的地址: <function deco.<locals>.wrapper at 0x0000023AA9FF58C8>

程序執(zhí)行到myfunc(1,2)的時候,本質(zhì)上是在執(zhí)行wrapper(1, 2),于是先輸出wrapper的地址,再執(zhí)行func()函數(shù)。執(zhí)行func()函數(shù)的時候,輸出myfunc()的地址,(可見,此時myfunc的值與wrapper的是相等),再打印3。當輸出func()函數(shù)的地址,可見func()函數(shù)的地址與myfunc()函數(shù)的地址不一樣了?。。?!這就是說,原來定義的myfunc()函數(shù)的函數(shù)體,已經(jīng)屬于func了,而不屬于myfunc了?。?/p>

進一步見證奇跡??!

def deco(func):
  def wrapper(*args, **kwargs): # *args, **kwargs用于接收func的參數(shù)
    pass
  return wrapper
@deco
def myfunc(a, b):
  print(a+b)
myfunc(1, 2)

該代碼沒有任何輸出。那是因為,執(zhí)行myfunc(1, 2)的時候,本質(zhì)上是執(zhí)行wrapper(1, 2)。而wrapper(1, 2)又不干任何事情,所以沒有輸出。至于print(a+b)這句話,他的地址已經(jīng)屬于func了。

帶參數(shù)的裝飾器,可以參見其他文章

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

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

相關(guān)文章

  • Python應(yīng)用自動化部署工具Fabric原理及使用解析

    Python應(yīng)用自動化部署工具Fabric原理及使用解析

    這篇文章主要介紹了Python應(yīng)用自動化部署工具Fabric原理及使用解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • Django ModelForm組件原理及用法詳解

    Django ModelForm組件原理及用法詳解

    這篇文章主要介紹了Django ModelForm組件原理及用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • python基礎(chǔ)_文件操作實現(xiàn)全文或單行替換的方法

    python基礎(chǔ)_文件操作實現(xiàn)全文或單行替換的方法

    下面小編就為大家?guī)硪黄猵ython基礎(chǔ)_文件操作實現(xiàn)全文或單行替換的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Python實現(xiàn)原神抽卡的方法

    Python實現(xiàn)原神抽卡的方法

    這篇文章主要為大家介紹了Python實現(xiàn)原神抽卡的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • python銀行卡號碼校驗Luhn模10算法

    python銀行卡號碼校驗Luhn模10算法

    這篇文章主要為大家介紹了python銀行卡號碼校驗Luhn模10算法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • Python Tricks 使用 pywinrm 遠程控制 Windows 主機的方法

    Python Tricks 使用 pywinrm 遠程控制 Windows 主機的方法

    這篇文章主要介紹了Python Tricks 使用 pywinrm 遠程控制 Windows 主機的方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • 如何在Python中引入和使用瀏覽器驅(qū)動

    如何在Python中引入和使用瀏覽器驅(qū)動

    本文介紹了如何在Python中引入和使用瀏覽器驅(qū)動,主要步驟包括安裝Selenium庫、下載并配置瀏覽器驅(qū)動路徑、編寫Python代碼啟動瀏覽器以及結(jié)束操作后關(guān)閉瀏覽器
    2025-01-01
  • Python?if?else語句對縮進的要求

    Python?if?else語句對縮進的要求

    這篇文章主要介紹了Python?if?else語句對縮進的要求,前面的一篇文章展示了選擇結(jié)構(gòu)的三種基本形式,并給出了實例演示,這篇文章基于上一篇內(nèi)容繼續(xù)對Python?if?else語句對縮進進行描述,需要的小伙伴可以參考一下
    2022-03-03
  • Python restful框架接口開發(fā)實現(xiàn)

    Python restful框架接口開發(fā)實現(xiàn)

    這篇文章主要介紹了Python restful框架接口開發(fā)實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • python實現(xiàn)跨年煙花動態(tài)效果

    python實現(xiàn)跨年煙花動態(tài)效果

    這篇文章主要介紹了python實現(xiàn)跨年煙花的動態(tài)效果,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-01-01

最新評論

安丘市| 通州市| 永胜县| 乌拉特前旗| 手机| 喜德县| 镇雄县| 临城县| 云和县| 通许县| 滦南县| 绥芬河市| 玉溪市| 鄂伦春自治旗| 广灵县| 林甸县| 连江县| 乡城县| 得荣县| 开化县| 旅游| 乌苏市| 鄂尔多斯市| 沙坪坝区| 泊头市| 石河子市| 昭平县| 顺平县| 广安市| 桐乡市| 墨竹工卡县| 三原县| 呼玛县| 大姚县| 光泽县| 澄城县| 额尔古纳市| 抚顺县| 绵竹市| 沙雅县| 尼玛县|