請教大家兩個Python裝飾器@的問題。
問題一:嵌套。
1 def Decorator2(plugger2):
2 plugger2()
3 print ("Plugger2 內(nèi)調(diào) here!")
4 def Decorator3(plugger3):
5 plugger3()
6 print ("Plugger3 內(nèi)調(diào) here!")
7 def DecoratorTesting():
8 @Decorator2
9 def plugger2():
10 print ("Plugger2 外調(diào) here!")
11 @Decorator3
12 def plugger3():
13 print ("Plugger3 外調(diào) here!")
最終運行DecoratorTesting()結(jié)果是:
Plugger2 外調(diào) here!
Plugger3 外調(diào) here!
Plugger3 內(nèi)調(diào) here!
Plugger2 內(nèi)調(diào) here!
我對DecoratorTesting()這個結(jié)果不太理解。當(dāng)?shù)?行@Decorator2的時候,難道不是應(yīng)該立即回到第1行打印“內(nèi)調(diào)”嗎?當(dāng)?shù)?1行@Decorator3的時候,難道不是應(yīng)該立即回到第4行打印“內(nèi)調(diào)”嗎?為什么結(jié)果卻是剛才的順序呢?
問題二:返回。
def go_Before(request, follow_up):
print ("Go to the before yields %s." %(request*2))
def go_After(request, follow_up):
print ("Go to the after yields %s." %(follow_up*3))
5 def Filter(before_func, after_func):
6 def f1(main_func):
7 def f2(request, follow_up):
8 before_result = before_func(request, follow_up)
9 if (before_result != None): return before_result;
10 main_result = main_func(request, follow_up)
11 if (main_result != None): return main_result;
12 after_result = after_func(request, follow_up)
13 if (after_result != None): return after_result;
14 return f2
15 return f1
@Filter(go_Before, go_After)
def go_Middle(request, follow_up):
print ("Go to the middle.")
最終運行g(shù)o_Middle('@', '#')結(jié)果是:
Go to the before yields @@.
Go to the middle.
Go to the after yields ###.
我對go_Middle()這個結(jié)果不太理解。第9行,應(yīng)該已經(jīng)徹底返回了??墒菫槭裁催€會繼續(xù)執(zhí)行第10行和以后的部分呢?
謝謝了先!
#先執(zhí)行@Decorator2裝飾的裝飾函數(shù)plugger2()
@Decorator2
def plugger2():
...
#等同于下面:
Decorator2(plugger2)
#即按照下面的流程來執(zhí)行,下面也是這個函數(shù)的整體流程,即先執(zhí)行plugger2(),最后再打印"plugger2內(nèi)調(diào)"
#再好好分析一下,下面這個流程就是這個函數(shù)執(zhí)行的流程,這里要弄明白。
plugger2()
print("Plugger2 內(nèi)調(diào) here!") #P4
這里就是你疑惑的關(guān)鍵點之一,實際上你明白了上面函數(shù)的執(zhí)行流程,你也就明白了為什么"plugger2內(nèi)調(diào)會最后打印了"
無論如何,print("Plugger2 內(nèi)調(diào) here!")會在plugger2()函數(shù)執(zhí)行完成之后再執(zhí)行,所以它一定會是最后執(zhí)行的語句
然后我們看plugger()函數(shù)是怎么執(zhí)行的:
9 def plugger2():
10 print ("Plugger2 外調(diào) here!") #P1
11 @Decorator3
12 def plugger3():
13 print ("Plugger3 外調(diào) here!")
#############################################
# 首先執(zhí)行print ("Plugger2 外調(diào) here!"),這也是整個函數(shù)最先執(zhí)行的一個print語句
# 然后plugger2里面又嵌套了一個裝飾器,按照上面的分析方式再來一次
Decorator3(plugger3)
||
||
\/
plugger3() # P2
print ("Plugger3 內(nèi)調(diào) here!") #P3
到了這里所有print順序都已經(jīng)理清楚了。按照我標(biāo)注的P1--P4的順序打印的。
第9行沒有結(jié)束的原因是:
before_func()沒有返回值,默認(rèn)返回None.
所以if before_result != None是不成立的,會繼續(xù)往下執(zhí)行。
第一題
記住下面的語法,再加一點細(xì)心便可理解
# PEP 318 -- Decorators for Functions and Methods
# https://www.python.org/dev/peps/pep-0318/
@dec2
@dec1
def func(arg1, arg2, ...):
pass
# 以上等同于以下
def func(arg1, arg2, ...):
pass
func = dec2(dec1(func))
像 DecoratorTesting ,可以轉(zhuǎn)變成
def DecoratorTesting():
def plugger2():
print("Plugger2 外調(diào) here!")
def plugger3():
print("Plugger3 外調(diào) here!")
plugger3 = Decorator3(plugger3)
plugger2 = Decorator2(plugger2)
第二題
我對go_Middle()這個結(jié)果不太理解。第9行,應(yīng)該已經(jīng)徹底返回了??墒菫槭裁催€會繼續(xù)執(zhí)行第10行和以后的部分呢?
其實第 9 行的條件并不成立
9 if (before_result != None): return before_result;
因為 go_Before 沒有顯式 return 語句, 默認(rèn)返回 None.
問題一:嵌套
def Decorator2(plugger2):
plugger2()
print ("Plugger2 內(nèi)調(diào) here!")
@Decorator2
def plugger2():
print ("Plugger2 外調(diào) here!")
@Decorator3
def plugger3():
print ("Plugger3 外調(diào) here!")
當(dāng)你使用裝飾器的時候等同用把下面的def 傳給了你裝飾器里面的形參 plugger2, plugger3 這是裝飾器里面運行形參這個def 代碼從上至下所以會限制性形參所指向的def運行這是就先出來外調(diào) 內(nèi)部裝飾器同樣的道理
問題二:返回
這個問題由于你 before_result = before_func(request, follow_up) 這個時候已經(jīng)調(diào)用了函數(shù),函數(shù)沒有返回值 導(dǎo)致北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達(dá)內(nèi)教育集團成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
北大課工場是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國制造2025”,實現(xiàn)中華民族偉大復(fù)興的升級產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團項目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。