真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

關(guān)于python@函數(shù)裝飾的信息

python裝飾器聽了N次也沒印象,讀完這篇你就懂了

裝飾器其實一直是我的一個"老大難"。這個知識點就放在那,但是拖延癥。。。

在鄒平等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站設(shè)計、做網(wǎng)站 網(wǎng)站設(shè)計制作按需求定制制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計,全網(wǎng)整合營銷推廣,外貿(mào)網(wǎng)站制作,鄒平網(wǎng)站建設(shè)費(fèi)用合理。

其實在平常寫寫腳本的過程中,這個知識點你可能用到不多

但在面試的時候,這可是一個高頻問題。

所謂的裝飾器,其實就是通過裝飾器函數(shù),來修改原函數(shù)的一些功能,使得原函數(shù)不需要修改。

這一句話理解起來可能沒那么輕松,那先來看一個"傻瓜"函數(shù)。

放心,絕對不是"Hello World"!

怎么樣,沒騙你吧? 哈哈,這個函數(shù)不用運(yùn)行相信大家都知道輸出結(jié)果: "你好,裝飾器" 。

那如果我想讓 hello() 函數(shù)再實現(xiàn)個其他功能,比如多打印一句話。

那么,可以這樣"增強(qiáng)"一下:

運(yùn)行結(jié)果:

很顯然,這個"增強(qiáng)"沒啥作用,但是可以幫助理解裝飾器。

當(dāng)運(yùn)行最后的 hello() 函數(shù)時,調(diào)用過程是這樣的:

那上述代碼里的 my_decorator() 就是一個裝飾器。

它改變了 hello() 的行為,但是并沒有去真正的改變 hello()函數(shù) 的內(nèi)部實現(xiàn)。

但是,python一直以"優(yōu)雅"被人追捧,而上述的代碼顯然不夠優(yōu)雅。

所以,想讓上述裝飾器變得優(yōu)雅,可以這樣寫:

這里的 @my_decorator 就相當(dāng)于舊代碼的 hello = my_decorator(hello) , @ 符號稱為語法糖。

那如果還有其他函數(shù)也需要加上類似的裝飾,直接在函數(shù)的上方加上 @my_decorator 就可以,大大提高函數(shù)

的重復(fù)利用與可讀性。

輸出:

上面的只是一個非常簡單的裝飾器,但是實際場景中,很多函數(shù)都是要帶有參數(shù)的,比如hello(people_name)。

其實也很簡單,要什么我們就給什么唄,直接在對應(yīng)裝飾器的 wrapper() 上,加上對應(yīng)的參數(shù):

輸出:

但是還沒完,這樣雖然簡單,但是隨之而來另一個問題:因為并不是所有函數(shù)參數(shù)都是一樣的,

當(dāng)其他要使用裝飾器的函數(shù)參數(shù)不止這個一個腫么辦?比如:

沒關(guān)系,在python里, *args 和 **kwargs 表示接受任意數(shù)量和類型的參數(shù),所以我們可以這樣

寫裝飾器里的 wrapper() 函數(shù):

同時運(yùn)行下 hello("老王") ,和 hello3("張三", "李四") ,看結(jié)果:

上面2種,裝飾器都是接收外來的參數(shù),其實裝飾器還可以接收自己的參數(shù)。

比如,我加個參數(shù)來控制下裝飾器中打印信息的次數(shù):

注意,這里 count 裝飾函數(shù)中的2個 return .

運(yùn)行下,應(yīng)該會出現(xiàn)3次:

現(xiàn)在多做一步 探索 ,我們來打印下下面例子中的hello()函數(shù)的元信息:

輸出:

這說明了,它不再是以前的那個 hello() 函數(shù),而是被 wrapper() 函數(shù)取代了。

如果我們需要用到元函數(shù)信息,那怎么保留它呢?這時候可以用內(nèi)置裝飾器 @functools.wrap 。

運(yùn)行下:

好記性不如爛筆頭,寫一下理解一下會好很多。

下面還分享類的裝飾器,以及裝飾器所用場景。

Python中的“ @”(@)符號有什么作用?

【@】符號在python中是裝飾器的意思。

裝飾器對一個可調(diào)用對象(函數(shù)、方法、類等等)進(jìn)行裝飾,它返回的也是一個可調(diào)用對象。

一般情況下,裝飾器是對被裝飾對象的修飾與增強(qiáng)。用現(xiàn)實事物類比的話,可以類比為中間商:中間商不生產(chǎn)產(chǎn)品,它將工廠生產(chǎn)的產(chǎn)品進(jìn)行包裝、運(yùn)輸后再銷售給顧客。裝飾器不實現(xiàn)核心功能,它提供對目標(biāo)函數(shù)調(diào)用的封裝與強(qiáng)。

它裝飾的方法返回值是一個對象(BillList、Bill、List[BillDetail]等),而裝飾器【enabled_cache】的作用如它的名稱一樣:使用緩存??梢钥吹?,這個裝飾器函數(shù)中定義了一個函數(shù)【wrapper】然后將這個wrapper作為返回值。這樣,原本調(diào)用ProductionBos.bill_with_last_week的代碼就不需要做任何改變就能享受到ProductionBos.bill_with_last_week原有的功能(得到一個BillList對象)和enabled_cache提供的附加功能(如果該對象有緩存,就不再從數(shù)據(jù)庫查詢)。

什么是Python裝飾器

裝飾器(decorator)是Python中的高級語法。裝飾的意思就是動態(tài)擴(kuò)展被裝飾對象的功能。裝飾器可以用于裝飾函數(shù)、方法和類。

一 嵌套函數(shù)

# 定義一個外層函數(shù)def foo(): # 定義了一個內(nèi)部函數(shù) def bar(): print("hello world")

函數(shù)bar是一個定義在foo函數(shù)內(nèi)部的函數(shù)。

Python中的函數(shù)是支持嵌套的,也就是可以在一個函數(shù)內(nèi)部再定義一個函數(shù)。

然后,我們還知道函數(shù)是可以當(dāng)作變量的,于是我們就可以在foo函數(shù)中把定義的這個bar函數(shù)返回。就像下面這樣:

# 定義一個外層函數(shù)def foo(): # 定義了一個內(nèi)層函數(shù) def bar(): print("hello world") return

barfunc = foo()func() # func -- bar,這里執(zhí)行func其實就相當(dāng)于執(zhí)行了在foo函數(shù)內(nèi)部定義的bar函數(shù)

二 閉包形態(tài)1

# 閉包形態(tài)1def foo(): name = "Andy" # 外部函數(shù)的局部變量 # 定義了一個內(nèi)部函數(shù) def bar():

print(name) # 雖然bar函數(shù)中沒有定義name變量,但是它可以訪問外部函數(shù)的局部變量name return barfunc =

foo()func() # func -- bar -- 除了是一個函數(shù),還包含一個值(它外層函數(shù)的局部變量)的引用

三 閉包形態(tài)2

# 閉包形態(tài)2def foo(name): # 給一個函數(shù)傳參也相當(dāng)于給函數(shù)定義了一個局部變量 # 定義了一個內(nèi)部函數(shù) def bar():

print(name) # 內(nèi)部函數(shù)同樣可以獲取到傳到外部函數(shù)的變量(參數(shù)) return barfunc = foo("Andy") #

把“Andy”當(dāng)成參數(shù)傳入foo函數(shù) -- 其內(nèi)部定義的bar函數(shù)也能拿到這個“Andy”func() # func -- bar --

除了是一個函數(shù),還包含一個值(它外層函數(shù)的參數(shù))的引用

四 裝飾器形態(tài)1

# 還是定義一個外層函數(shù)def foo(name): # 我接收的參數(shù)是一個函數(shù)名 # 定義了一個內(nèi)部函數(shù) def bar():

print("這是新功能。。。") # 新功能 name() # 函數(shù)名加()就相當(dāng)于執(zhí)行-- 我傳進(jìn)來原函數(shù)的函數(shù)名,這里就相當(dāng)于執(zhí)行了原函數(shù)

return bar# 定義一個被裝飾的函數(shù)def f1(): print("hello world.") # 用foo函數(shù)裝飾f1函數(shù)f1 =

foo(f1)# 不改變f1的調(diào)用方式f1() # -- 此時函數(shù)已經(jīng)擴(kuò)展了新功能

五 裝飾器形態(tài)2

# 還是定義一個外層函數(shù)def foo(name): # 接收的參數(shù)是一個函數(shù)名 # 定義了一個內(nèi)部函數(shù) def bar():

print("這是新功能。。。") # 新功能 name() # 函數(shù)名加()就相當(dāng)于執(zhí)行-- 傳進(jìn)來原函數(shù)的函數(shù)名,這里就相當(dāng)于執(zhí)行了原函數(shù)

return bar# 定義一個被裝飾的函數(shù)# 用foo函數(shù)裝飾f1函數(shù)@foo # 使用f1 =

foo(f1)語法裝飾的話稍顯啰嗦,Python就提供了@語法,讓裝飾過程更簡便def f1(): print("hello world.") #

不改變f1的調(diào)用方式f1() # -- 此時函數(shù)已經(jīng)擴(kuò)展了新功能。

python函數(shù)修飾符@的使用

python函數(shù)修飾符@ 修飾符 ‘@’符號用作函數(shù)修飾符是python2.4新增加的功能,修飾符必須出現(xiàn)在函數(shù)定義前一行,不允許和函數(shù)定義在同一行。也就是說@A def f(): 是非法的。 只可以在模塊或類定義層內(nèi)對函數(shù)進(jìn)行修飾,不允許修修飾一個類。一個修飾符就是一個函數(shù),它將被修飾的函數(shù)做為參數(shù),并返回修飾后的同名函數(shù)或其它可調(diào)用的東西。 本質(zhì)上講,裝飾符@類似于 回調(diào)函數(shù) ,把其它的函數(shù)(暫且稱為目的參數(shù),后面緊接著的函數(shù))作為自己的入?yún)?,在目的函?shù)執(zhí)行前,執(zhí)行一些自己的操作, 比如:計數(shù)、打印一些提示信息等,然后返回目的函數(shù)。下面列舉一個簡單的例子。

創(chuàng)建函數(shù)修飾符的規(guī)則:

(1)修飾符是一個函數(shù)

(2)修飾符取被修飾函數(shù)為參數(shù)

(3)修飾符返回一個新函數(shù)

(4)修飾符維護(hù)被維護(hù)函數(shù)的簽名

例子1: 被修飾函數(shù)不帶參數(shù)

運(yùn)行結(jié)果:

例子2: 使用functools模塊提供的修改函數(shù)屬性的方法wraps

運(yùn)行結(jié)果:

可見test1的函數(shù)名稱變了,如果某些代碼用到就會出問題,可以使用functools模塊提供的修改函數(shù)屬性的方法wraps

運(yùn)行結(jié)果:

例子3: 被修飾函數(shù)帶參數(shù)

運(yùn)行結(jié)果:

例子4: 修飾符帶參數(shù) ,需要比上面例子多一層包裝

運(yùn)行結(jié)果:

Python筆記:Python裝飾器

裝飾器是通過裝飾器函數(shù)修改原函數(shù)的一些功能而不需要修改原函數(shù),在很多場景可以用到它,比如① 執(zhí)行某個測試用例之前,判斷是否需要登錄或者執(zhí)行某些特定操作;② 統(tǒng)計某個函數(shù)的執(zhí)行時間;③ 判斷輸入合法性等。合理使用裝飾器可以極大地提高程序的可讀性以及運(yùn)行效率。本文將介紹Python裝飾器的使用方法。

python裝飾器可以定義如下:

輸出:

python解釋器將test_decorator函數(shù)作為參數(shù)傳遞給my_decorator函數(shù),并指向了內(nèi)部函數(shù) wrapper(),內(nèi)部函數(shù) wrapper() 又會調(diào)用原函數(shù) test_decorator(),所以decorator()的執(zhí)行會先打印'this is wrapper',然后打印'hello world', test_decorator()執(zhí)行完成后,打印 'bye' ,*args和**kwargs,表示接受任意數(shù)量和類型的參數(shù)。

裝飾器 my_decorator() 把真正需要執(zhí)行的函數(shù) test_decorator() 包裹在其中,并且改變了它的行為,但是原函數(shù) test_decorator() 不變。

一般使用如下形式使用裝飾器:

@my_decorator就相當(dāng)于 decorator = my_decorator(test_decorator) 語句。

內(nèi)置裝飾器@functools.wrap可用于保留原函數(shù)的元信息(將原函數(shù)的元信息,拷貝到對應(yīng)的裝飾器函數(shù)里)。先來看看沒有使用functools的情況:

輸出:

從上面的輸出可以看出test_decorator() 函數(shù)被裝飾以后元信息被wrapper() 函數(shù)取代了,可以使用@functools.wrap裝飾器保留原函數(shù)的元信息:

輸出:

裝飾器可以接受自定義參數(shù)。比如定義一個參數(shù)來設(shè)置裝飾器內(nèi)部函數(shù)的執(zhí)行次數(shù):

輸出:

Python 支持多個裝飾器嵌套:

裝飾的過程:

順序從里到外:

test_decorator('hello world') 執(zhí)行順序和裝飾的過程相反。

輸出:

類也可以作為裝飾器,類裝飾器主要依賴__call__()方法,是python中所有能被調(diào)用的對象具有的內(nèi)置方法(python魔術(shù)方法),每當(dāng)調(diào)用一個類的實例時,__call__()就會被執(zhí)行一次。

下面的類裝飾器實現(xiàn)統(tǒng)計函數(shù)執(zhí)行次數(shù):

輸出:

下面介紹兩種裝飾器使用場景

統(tǒng)計函數(shù)執(zhí)行所花費(fèi)的時間

輸出:

在使用某些web服務(wù)時,需要先判斷用戶是否登錄,如果沒有登錄就跳轉(zhuǎn)到登錄頁面或者提示用戶登錄:

--THE END--


網(wǎng)站名稱:關(guān)于python@函數(shù)裝飾的信息
網(wǎng)頁地址:http://weahome.cn/article/hjsgdh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部