python裝飾器設(shè)置參數(shù)方式
前言
一開(kāi)始沒(méi)打算寫(xiě)這篇文章的,今天整理筆記看到了偏函數(shù)的帖子在拿裝飾器舉例對(duì)比。
然后就想到既然裝飾器本身也是函數(shù),為啥不可以給裝飾器也設(shè)置上參數(shù),來(lái)進(jìn)一步提高裝飾器的復(fù)用性呢?
于是把思路整理了一下,就有了本文。
裝飾器原理回顧
在我的另一篇關(guān)于裝飾器的文章中有跟大家提到過(guò),裝飾器實(shí)際上就是一個(gè)閉包函數(shù),在閉包函數(shù)的內(nèi)部函數(shù)中添加裝飾的內(nèi)容并調(diào)用被裝飾的函數(shù)。
以達(dá)到 fun = decorator(fun) 的效果:
def decorator(fun): def inner(name): print("Hi") fun(name) return inner @decorator def get_last_name(name): print(f"你就是小{name[0]}吧") get_last_name("王富貴")
從上面的例子中我們可以簡(jiǎn)單的總結(jié)出裝飾器不同參數(shù)設(shè)置的規(guī)律:
裝飾器外部的函數(shù)傳的參數(shù)是被裝飾函數(shù)的函數(shù)名,內(nèi)部函數(shù)的參數(shù)是被裝飾函數(shù)的參數(shù)。
使用裝飾器時(shí),被裝飾函數(shù)的參數(shù)name是先傳遞給裝飾器的內(nèi)部函數(shù),內(nèi)部函數(shù)調(diào)用被裝飾函數(shù)時(shí)將參數(shù)name傳遞給被裝飾函數(shù)。
而外部函數(shù)接收的參數(shù)時(shí)被裝飾函數(shù)的函數(shù)名,注意,外部函數(shù)的參數(shù)只能有一個(gè)也只能是被裝飾函數(shù)的函數(shù)名。
"""錯(cuò)誤寫(xiě)法""" def decorator(fun,*args_outer): def inner(*args_inner): pass
一個(gè)很簡(jiǎn)單的道理,裝飾器的用法是@+裝飾器名+被裝飾函數(shù)。
其工作原理就是fun = decorator(fun) ,即裝飾器接收的第一個(gè)參數(shù)就必須是被裝飾函數(shù)名,如果設(shè)置其他參數(shù)的話在第一個(gè)參數(shù)都缺失的情況下怎么傳?
不過(guò)并不是完全沒(méi)辦法,換一換思路就可以了,下面就是本文要講的干貨了
裝飾器設(shè)置參數(shù):多層閉包嵌套
?我們都知道,裝飾器就是一個(gè)閉包函數(shù),外部接收被裝飾函數(shù)名,內(nèi)部裝飾再調(diào)用被裝飾函數(shù)。
那么我們?yōu)樯恫辉谶@個(gè)閉包函數(shù)的外部再嵌套一層函數(shù)用來(lái)接收自己想要的參數(shù)呢?
廢話不多說(shuō),舉例子上代碼:
"""假設(shè)一家燒烤店可以送外賣,外賣比堂食要多出打包盒跟配送費(fèi)兩項(xiàng)費(fèi)用""" def decorator_outer(*args_outer): # 接收正常在店內(nèi)消費(fèi)之外的其他費(fèi)用 def decorator_inner(fun): def inner(*args_inner): # 接收在正常參數(shù)的費(fèi)用 new_args = args_outer + args_inner return fun(*new_args) return inner return decorator_inner @decorator_outer(3,5) # 打包盒3元,配送費(fèi)5元 def monetary(*args): # 計(jì)算每份菜品價(jià)格之和 themoney = 0 for m in args: themoney += m return themoney
上一次的文章說(shuō)到,閉包調(diào)用內(nèi)部函數(shù)的方法是decorator()(),那么類似上述代碼中多嵌套了一層就自然是decorator_outer()()()。
也就是說(shuō)按照裝飾器的工作原理,上述代碼的工作原理就是
monetary = decorator_outer(3,5)(monetary)
小小的提醒一下,閉包嵌套層次越多就一定要注意看看被裝飾函數(shù)的返回值有沒(méi)有被一層層的返回出來(lái),不然最后返回一個(gè)空值又不報(bào)錯(cuò)很難排查。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Qt調(diào)用Python詳細(xì)圖文過(guò)程記錄
Qt調(diào)用python實(shí)際上就是c++調(diào)python,網(wǎng)上搜會(huì)出來(lái)很多,介紹得也比較全,這里做個(gè)記錄,下面這篇文章主要給大家介紹了關(guān)于Qt調(diào)用Python詳細(xì)圖文過(guò)程,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05python?包?requests?實(shí)現(xiàn)請(qǐng)求操作
這篇文章主要介紹了python?包?requests?實(shí)現(xiàn)請(qǐng)求操作,文章介紹內(nèi)容包括帶參數(shù)請(qǐng)求、自定義headers,文章內(nèi)容詳細(xì)具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-04-04python使用Turtle庫(kù)繪制動(dòng)態(tài)鐘表
這篇文章主要為大家詳細(xì)介紹了python使用Turtle庫(kù)繪制動(dòng)態(tài)鐘表,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11python numpy數(shù)組復(fù)制使用實(shí)例解析
這篇文章主要介紹了python numpy數(shù)組復(fù)制使用實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01利用python循環(huán)創(chuàng)建多個(gè)文件的方法
今天小編就為大家分享一篇利用python循環(huán)創(chuàng)建多個(gè)文件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10Python中json模塊load/loads方法實(shí)戰(zhàn)以及參數(shù)詳解
經(jīng)常在Python中對(duì)JSON格式的文件進(jìn)行操作,今天對(duì)這些操作做一個(gè)總結(jié),下面這篇文章主要給大家介紹了關(guān)于Python中json模塊load/loads方法實(shí)戰(zhàn)以及參數(shù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08詳解Python自帶的日期日歷處理calendar庫(kù)的使用
在?Python?開(kāi)發(fā)中,我們經(jīng)常需要處理日期和時(shí)間,雖然?datetime?庫(kù)是最常用的選擇,但其實(shí)?Python?標(biāo)準(zhǔn)庫(kù)中的?calendar?模塊也是一個(gè)強(qiáng)大的工具,下面我們就來(lái)看看它的具體使用吧2024-12-12