12 前方高能 裝飾器高階

2022-05-16 20:48:23 字數 4415 閱讀 8574

本節主要內容:

1.通過裝飾器回顧

2.函式的有用資訊

3.帶引數的裝飾器

4.多個裝飾器同時裝飾乙個函式

一.通過裝飾器回顧

開閉原則:對增加功能開放,對修改**封閉

裝飾器的作用:在不改變原有**的基礎上給乙個函式增加功能

同用裝飾器的寫法:

def inner(*args,**kwargs):

"""在目標函式之前做的事情

"""ret =fn(*args,**kwargs)

"""在目標函式之後做的事情

"""return

ret

return

inner

def target_func():

print(

"目標函式

") #"""

目標函式

"""target_func() #函式呼叫

執行過程:

2.當執行到target_func的時候,我們實際上執行的是inner函式,inner函式會先執行目標函式之前的**,然後再執行你的目標函式,執行完目標函式最後執行的是目標函式之後的**

二.函式的有用資訊

1.如何給函式新增注釋

def chi(food,drink):

"""這裡是函式的注釋,先寫一下當前這個函式是幹什麼的,比如我這個函式就是乙個吃

:param food: 引數food是什麼意思

:param drink: 引數drink是什麼意思

:return

: 返回的是什麼東東

"""print(food,drink)

return

"very good

"

2.如何獲取帶函式的相關資訊

def chi(food,drink):

"""這裡是函式的注釋,先些一下當前這個函式是幹什麼的,比如我這個函式就是乙個吃

:param food: 引數food是什麼意思

:param drink: 引數drink是什麼意思

:return

: 返回的是什麼東東

"""print(food,drink)

"""這個可以獲取到麼

"""print(chi.__doc__) # 獲取函式的文件注釋

print(chi.__name__) #獲取到函式名稱

return

"very good

"chi(

"吃嘛嘛香

","我不想吃")

print(chi.__doc__)

print(chi.__name__)

函式名.__name__可以檢視函式的名字

函式名.__doc__可以檢視函式的文件注釋

接下來,我們來看一看被裝飾器裝飾之後的函式名:

def inner(*args,**kwargs):

"""在執行目標函式之前要執行的內容

"""ret = func(*args,**kwargs)

return

ret

return

inner

def target_func():

print(

"我是目標函式")

target_func() #呼叫函式

print(target_func.__name__) #inner

我們雖然訪問的是target_func函式,但是實際上執行的是inner函式,這樣就會給下游的程式設計師帶倆困惑,之前不是一直執行的是target_func麼,為什麼突然換成了inner,inner是個什麼鬼??為了不讓下游程式設計師有這樣的困惑,我們需要把函式名修改一下,具體修改方案:

from

functools import wraps # 引入函式模組

#裝飾器:對傳遞進來的函式進行包裝,可以在目標函式之前和之後新增任意功能.

@wraps(func) #使用函式原來的名字

def inner(*args,**kwargs):

"""在執行目標函式之前要執行的內容

"""ret = func(*args,**kwargs)

"""在執行目標函式之後要執行的內容

"""return

ret

return

inner

def target_func():

print(

"我是目標函式")

#呼叫目標函式

target_func()

print(target_func.__name__) #不在是inner,而是target_func了

def new_target_func():

print(

"我是另乙個目標函式")

new_target_func()

print(new_target_func.__name__) # 不在是inner,而是new_target_func

ps:*args和**kwargs什麼時候打散,什麼時候聚合

1.接收引數的時候聚合,引數宣告

2.傳遞引數的時候打散,給函式傳遞實參

# @wraps(func)

def inner(*args,**kwargs): #這裡是聚合

"""在執行目標函式之前要執行的內容

"""ret = func(*args,**kwargs) #這裡是打散,這裡的作用,其實就是為了保證我可以裝飾所有函式而準備的

"""在執行目標函式之後要執行的內容

"""return

ret

return inner

三.裝飾器傳參

現在來這樣乙個場景,還是昨天的約。

from

functools import wraps

@wraps(fn)

def inner(*args,**kwargs): #這裡是聚合

print(

"問問金老闆啊,**怎麼樣。

") #在執行目標函式之前要指向性的內容

ret =fn(*args,**kwargs)

print(

"++,金老闆騙我

") #在執行目標函式之後要執行的內容

return

ret

return

inner

def yue():

print(

"約一次又不會死")

yue() #函式呼叫

那麼現在如果查的嚴,怎麼辦呢?打**問金老闆嚴不嚴,那如果整體風聲都不是那麼緊呢,是不是就不需要問金老闆了,所以,我們需要乙個開關來控制是否要詢問金老闆,這時我們就需要給裝飾器傳遞乙個引數,來通知裝飾器要用怎麼樣的方式來裝飾你的目標函式

from

functools import wraps #引入乙個模組

@wraps(fn)

def inner(*args,**kwargs):

if flag ==true: #查的嚴不嚴呀,先問問吧

print(

"問問金老闆呀,**怎麼樣。")

ret = fn(*args,**kwargs)

print(

"++,金老闆騙我")

return

ret

else

: # 查的不嚴,你慌什麼

ret =fn(*args,**kwargs)

return

ret

return

inner

return

def yue():

print(

"約一次又不會死")

yue()

四.多個裝飾器裝飾同乙個函式

先讀一下這樣乙個**

def inner(*args,**kwargs):

print(

"111")

ret =fn(*args,**kwargs)

print(

"222")

return

ret

return

inner

def inner(*args,**kwargs):

print(

"333")

ret =fn(*args,**kwargs)

print(

"444")

return

ret

return

inner

def eat():

print(

"我想吃水果")

eat()

第二層裝飾器前(第一層裝飾器前(目標)第一層裝飾器後)第二層裝飾器後。程式從左到右執行起來,就是我們看到的結果

day12 裝飾器高階

day12 裝飾器高階 裝飾器高階 functools.wraps 帶引數的裝飾器 多個裝飾器裝飾用乙個函式 def outer args,kwargs 接收的時候是聚合 成元祖的形式 print args print args def inner args print inner args inn...

python學習day12 裝飾器高階

裝飾器的高階 functools.wraps 帶引數的裝飾器 多個裝飾器裝飾同乙個函式 裝飾器 開發原則 開放封閉原則 裝飾器的作用 在不改變原函式的呼叫方式的情況下,在函式的前後新增功能 裝飾器的本質 閉包函式 def inner args,kwargs print 在被裝飾的函式執行之前做的事 ...

裝飾器高階

有參 在標準裝飾器的外層,套了一層就需要額外的呼叫一程 語法糖 裝飾器 引數 帶參修飾器 while true def count a def func f def fool args,kwargs if a 1 print 這是第乙個裝飾的函式qq f args,kwargs if a 2 f a...