為什麼python的裝飾器要雙層巢狀?

時間 2021-10-28 23:55:37

1樓:無名

努力寫個簡短而又通俗的回答!

@decorator

defmy_func

(...

):...

等價於:

defmy_func

(...

):...

my_func

=decorator

(my_func

)可見裝飾器是乙個函式,它的input是原函式,output是裝飾後的函式。在裝飾器裡,基於原函式,構造出乙個新函式,看起來就像是雙層巢狀。

defdecorator

(raw_func

):# 原函式作為input

defdecorated_func

(...

):# 構造乙個新的函式

...return

decorated_func

# 返回構造出來的新函式來替換原函式

對於帶引數的裝飾器,原理也一樣。

@decorator_maker

(...

)def

my_func

(...

):...

等價於:

defmy_func

(...

):...

decorator

=decorator_maker

(...

)my_func

=decorator

(my_func

)帶引數的裝飾器,實際上是先呼叫了這個「裝飾器的生成函式」,得到了乙個裝飾器,再用返回的這個裝飾器做裝飾,所以又多了一層巢狀。

defdecorator_maker

(...

):def

real_decorator

(raw_func

):# 根據引數建立乙個裝飾器

defdecorated_func

(...

):...

return

decorated_func

return

real_decorator

# 返回建立好的裝飾器

2樓:五四青年

1.因為外層函式的引數是被裝飾的函式,所以閉包起碼有外層+內層兩層函式

2.多少層都可以(比如flask),例如:

defouter1(*

args1,**

kwargs1

):# 增加某些功能1

defouter2(*

args2,**

kwargs2

):# 增加某些功能2

defouter3(*

args3,**

kwargs3

):# Test被放在了這裡

def_in(*

args,**

kwargs

):# 最內層函式

args3[0

]()# 這裡呼叫了Test函式

return

_inreturn

outer3

return

outer2

@outer1

("outer1"

)("outer2"

)# 可以通過傳入引數來進行「裝飾」的功能

defTest

():print

("Hello World")if

__name__

=="__main__"

:Test

()# 可以發現在_in函式呼叫前,所有的外部函式都已經跑了一遍

除了最內一層_in函式,外層的函式都是為了最內層服務的(為in函式增加某一些功能),正如「裝飾器」的「裝飾」名字所表述的,人如其名啊有木有,核心是最內層函式,在外部每增加一層函式就能多乙個功能的增加,比如cookie驗證?比如....反正你想在in函式啟動之前先做哪些準備工作,都能在outer1,outer2,outer3...

函式中先準備起來

為什麼要用閉包,我覺得是為了在Test函式在啟動之前,能夠立刻將外層的那些函式「調動」起來,從而使得Test函式有更強大,更加完善的功能;

就好比乙個跑步運動員比賽時,除了自身平時的訓練,一雙好的鞋子和降阻力服飾也是必要的,跑鞋和服裝的功能,在運動員啟動之前就是已經裝備好了的....

如何理解python的描述器和裝飾器?

秦仲子 好傢伙,這一堆答案就沒個簡單明瞭的,讓我來。1.裝飾器 有個裝飾器函式funcA,有個被裝飾的函式funcB,如果用funcA裝飾funcB,那麼後續的呼叫時funcB執行效果就funcA funcB python用 符號完成了裝飾器模式,很好的遵循了開閉原則,應用於授權,日誌等場景,還實現...

什麼時候會用到python裝飾器?

decorator factory from functools import wraps defmax result threshold def decorator func wraps func def args,kwargs result func args,kwargs if result ...

惡補了 Python 裝飾器的八種寫法,你隨便問

沉憶 看個人追求吧,如果單純把籃球當作是娛樂鍛鍊,那最好是盡量從以突破得分轉變到投籃得分,如果是想打好,有追求的話,建議多練練大腿肌肉,這樣可以有效的減少對膝蓋的負擔,打球前盡量多熱熱身,拉伸開來。對於裝備的話,想保護膝蓋,一定要戴上護膝,鞋盡量選減震好的 ZOOM都還行,阿迪的沒錢沒試過 中國產的...