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

通俗易懂了解Python裝飾器原理

 更新時(shí)間:2020年09月17日 08:30:16   作者:mskitten  
這篇文章主要介紹了通俗易懂了解Python裝飾器原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

作用

裝飾器可以用于用于裝飾一個(gè)函數(shù)或方法,使得在不修改原函數(shù)、方法代碼的前提下,為方法添加前置或后置操作;

例如突然想要計(jì)算一下各個(gè)函數(shù)的執(zhí)行時(shí)間,又不希望在每一個(gè)函數(shù)中添加tim.time()來(lái)計(jì)算執(zhí)行時(shí)間

用法

裝飾器的寫法網(wǎng)上很多,但是我覺(jué)得還是盡量先理解,再知道怎么寫會(huì)比較好,所以會(huì)先說(shuō)如何理解,在后面重寫用法

實(shí)現(xiàn)

了解裝飾器是如何實(shí)現(xiàn)的,遠(yuǎn)比會(huì)寫裝飾器更重要,簡(jiǎn)單的說(shuō)裝飾器就是接收一個(gè)函數(shù)對(duì)象,然后先執(zhí)行前置操作,再執(zhí)行函數(shù),再執(zhí)行后置操作;

這么說(shuō)可能有些抽象,或者舉一個(gè)不那么恰當(dāng)?shù)谋容^貼近生活的例子;

假設(shè)你有一臺(tái)像這樣的小風(fēng)扇:

這臺(tái)風(fēng)扇可以充電,有一個(gè)開關(guān),打開之后扇葉會(huì)旋轉(zhuǎn),開始工作,當(dāng)然你也可以插著電打開開關(guān),也可以充好電之后帶走,在其他地方打開開關(guān)

如果把這個(gè)風(fēng)扇置于一切皆是對(duì)象的Python中,風(fēng)扇就是一個(gè)對(duì)象,他實(shí)現(xiàn)的功能就是出風(fēng):

def fengshan():
  return '出風(fēng)'

為了更好和例子結(jié)合,我們用pinyin命名

現(xiàn)在我們實(shí)現(xiàn)了一個(gè)fengshan函數(shù),返回吹風(fēng)

如果你稍微有點(diǎn)基礎(chǔ),你就能知道如何調(diào)用這個(gè)方法

def fengshan():
  return '出風(fēng)'
print(fengshan())

不要覺(jué)得這很基礎(chǔ)很墨跡,如果需要理解裝飾器,你必須知道,調(diào)用函數(shù)的方式是函數(shù)名稱加上括號(hào)fengshan()
而這個(gè)基礎(chǔ)中的基礎(chǔ)中的括號(hào)()就是執(zhí)行函數(shù)的開關(guān),如果我們不加括號(hào)

def fengshan():
  return '出風(fēng)'
print(fengshan)

返回的將是一個(gè)函數(shù)對(duì)象(例子中的風(fēng)扇本身)

<function fengshan at 0x7f8e7c4a6950>

這里的意思是 一個(gè)叫fengshan的funciont,地址在0x7f8e7c4a6950

那現(xiàn)在我們就可以把風(fēng)扇帶走,在其他地方使用

def fengshan():
  return '出風(fēng)'
 
func = fengshan
print(fengshan)
print(func)

返回

<function fengshan at 0x7f570eaf3950>
<function fengshan at 0x7f570eaf3950>

這說(shuō)明func和fengshan是等價(jià)的,他們?cè)谕粔K內(nèi)存中,所以當(dāng)我們執(zhí)行func() 也等價(jià)于執(zhí)行fengshan

def fengshan():
  return '出風(fēng)'
 
func = fengshan
print('下面是執(zhí)行fengshan')
print(fengshan())
print('下面是執(zhí)行func')
print(func())

返回

下面是執(zhí)行fengshan

出風(fēng)

下面是執(zhí)行func

出風(fēng)

理解到這里之后你也就能理解裝飾器的實(shí)現(xiàn)了,讓我們?cè)倏匆粋€(gè)例子

def fengshan():
  return '出風(fēng)'
def wrapper(func):
  return func
print(fengshan)
print(wrapper(fengshan))

這個(gè)例子中我們除了保留剛剛一直在用的fengshan函數(shù)之外,又定義了一個(gè)wrapper

因?yàn)閜ython中一切皆是對(duì)象,函數(shù)也是對(duì)象,而函數(shù)的入?yún)⒁部梢越邮諏?duì)象,所以函數(shù)對(duì)象可以作為參數(shù)傳遞給另一個(gè)函數(shù)wrapper

這個(gè)wrapper中什么都沒(méi)有做,只是返回了接收的func對(duì)象,我們打印出來(lái)兩個(gè)對(duì)象,可以發(fā)現(xiàn)他們其實(shí)是同一個(gè)對(duì)象

<function fengshan at 0x7f9b0c92f950>
<function fengshan at 0x7f9b0c92f950>

現(xiàn)在你就已經(jīng)理解了裝飾器的實(shí)現(xiàn)了,而且如果你跟著文中的代碼敲一遍,你就已經(jīng)寫了一個(gè)裝飾器,你只需要稍加修改,比方說(shuō),我們?cè)趙rapper內(nèi)部執(zhí)行接收的func,并且,在前后加上一些操作

def wrapper(func):
  print('在wrapper中執(zhí)行func前')
  print(func())
  print('在wrapper中執(zhí)行func后')
wrapper(fengshan)

返回

在wrapper中執(zhí)行func前

出風(fēng)

在wrapper中執(zhí)行func后

如果你覺(jué)得很神奇,無(wú)法理解,可以回到風(fēng)扇的圖片重新再讀一遍,當(dāng)你理解了上述的代碼之后,我們就可以加快速度,完成真正的裝飾器的編寫

用法

當(dāng)你成功明白了函數(shù)被定義和調(diào)用的過(guò)程之后,我們開始考慮實(shí)際場(chǎng)景,上一段代碼中我們還是改變了原有函數(shù)的調(diào)用

從調(diào)用fengshan變成了調(diào)用func(fengshan)

我們想要實(shí)現(xiàn)不改變?cè)写a和調(diào)用方式的情況下為原有函數(shù)添加前置或后置操作,就需要再優(yōu)化一下我們的裝飾器

def fengshan():
  print('出風(fēng)')
 
 
def wrapper(func):
  def f():
    print('在wrapper中執(zhí)行func前')
    func()
    print('在wrapper中執(zhí)行func后')
  return f
 
fengshan = wrapper(fengshan)
fengshan()

為了看到執(zhí)行過(guò)程,我們把fengshan內(nèi)部的return改為print

返回

在wrapper中執(zhí)行func前

出風(fēng)

在wrapper中執(zhí)行func后

這里我們的改變是在wrapper原有的實(shí)現(xiàn)中又包了一層方法f,再回想一下我們前面風(fēng)扇的例子,現(xiàn)在當(dāng)我們執(zhí)行wrapper的時(shí)候,執(zhí)行了什么?

wrapper(func)的返回,是一個(gè)函數(shù)對(duì)象f,這個(gè)函數(shù)對(duì)象的開關(guān)沒(méi)有被打開,f中的代碼不會(huì)被執(zhí)行

我們又用同名的fengshan對(duì)象去接收了這個(gè)函數(shù)對(duì)象f,在最后一行打開fengshan的開關(guān) -- fengshan(),這時(shí)候函數(shù)對(duì)象f中的代碼,才剛被執(zhí)行

如果看不懂的話,建議從風(fēng)扇圖片開始再看一遍,如果你看懂了,建議你也再看一遍,至此,我們就已經(jīng)完成了一個(gè)裝飾器,為了更方便使用裝飾器,Python給我們提供了更簡(jiǎn)便的方法

def wrapper(func):
  def f():
    print('在wrapper中執(zhí)行func前')
    func()
    print('在wrapper中執(zhí)行func后')
  return f
@wrapper
def fengshan():
  print('出風(fēng)')
fengshan()

返回

在wrapper中執(zhí)行func前

出風(fēng)

在wrapper中執(zhí)行func后

補(bǔ)充知識(shí)

如果你已經(jīng)理解了裝飾器的執(zhí)行邏輯,你也就會(huì)知道如何讓裝飾器支持帶參數(shù)的方法,這也是我們寫裝飾器的常規(guī)操作

def wrapper(func):
  def f(*args, **kwargs):
    print('在wrapper中執(zhí)行func前')
    func(*args, **kwargs)
    print('在wrapper中執(zhí)行func后')
  return f
@wrapper
def fengshan(str_obj):
  print(str_obj)
fengshan(str_obj='出風(fēng)')

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python進(jìn)程間通信Queue消息隊(duì)列用法分析

    Python進(jìn)程間通信Queue消息隊(duì)列用法分析

    這篇文章主要介紹了Python進(jìn)程間通信Queue消息隊(duì)列用法,結(jié)合實(shí)例形式分析了基于Queue的進(jìn)程間通信相關(guān)操作技巧與使用注意事項(xiàng),需要的朋友可以參考下
    2019-05-05
  • python內(nèi)置數(shù)據(jù)類型之列表操作

    python內(nèi)置數(shù)據(jù)類型之列表操作

    數(shù)據(jù)類型是一種值的集合以及定義在這種值上的一組操作。這篇文章主要介紹了python內(nèi)置數(shù)據(jù)類型之列表的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-11-11
  • python 進(jìn)程的幾種創(chuàng)建方式詳解

    python 進(jìn)程的幾種創(chuàng)建方式詳解

    這篇文章主要介紹了python 進(jìn)程的幾種創(chuàng)建方式詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Django 創(chuàng)建/刪除用戶的示例代碼

    Django 創(chuàng)建/刪除用戶的示例代碼

    這篇文章主要介紹了Django 創(chuàng)建/刪除用戶的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • python提取視頻中的音頻的實(shí)現(xiàn)示例

    python提取視頻中的音頻的實(shí)現(xiàn)示例

    MoviePy是一個(gè)用于視頻編輯的庫(kù),它可以提取視頻中的音頻并保存為音頻文件,本文主要介紹了python提取視頻中的音頻的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2024-03-03
  • pytorch?ssim計(jì)算詳細(xì)代碼例子

    pytorch?ssim計(jì)算詳細(xì)代碼例子

    這篇文章主要給大家介紹了關(guān)于pytorch?ssim計(jì)算的相關(guān)資料,結(jié)構(gòu)相似性(SSIM)是一種測(cè)量?jī)煞鶊D像的相似度的方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • 關(guān)于Python?中IndexError:list?assignment?index?out?of?range?錯(cuò)誤解決

    關(guān)于Python?中IndexError:list?assignment?index?out?of?rang

    這篇文章主要介紹了Python?中IndexError:list?assignment?index?out?of?range?錯(cuò)誤解決,概述了兩個(gè)常見(jiàn)的列表函數(shù),它們可以幫助我們?cè)谔鎿Q兩個(gè)列表時(shí)幫助我們處理?Python?中的索引錯(cuò)誤,需要的朋友可以參考下
    2023-05-05
  • 深入了解Python中反射和動(dòng)態(tài)屬性的無(wú)限可能

    深入了解Python中反射和動(dòng)態(tài)屬性的無(wú)限可能

    理解 Python 中的反射和動(dòng)態(tài)屬性是編寫靈活和強(qiáng)大程序的關(guān)鍵,在這篇文章中,小編將帶領(lǐng)大家一起反射和動(dòng)態(tài)屬性的概念,并提供大量示例代碼,希望對(duì)大家有所幫助
    2023-11-11
  • python?pytorch圖像識(shí)別基礎(chǔ)介紹

    python?pytorch圖像識(shí)別基礎(chǔ)介紹

    大家好,本篇文章主要講的是python?pytorch圖像識(shí)別基礎(chǔ)介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02
  • python文件名和文件路徑操作實(shí)例

    python文件名和文件路徑操作實(shí)例

    下面小編就為大家?guī)?lái)一篇python文件名和文件路徑操作實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09

最新評(píng)論