在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Python  C/ 請教Python裝飾器@嵌套順序的問題

請教Python裝飾器@嵌套順序的問題

請教大家兩個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行和以后的部分呢?

謝謝了先!

回答
編輯回答
女流氓

問題1:DecoratorTesting()的執(zhí)行順序

#先執(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的順序打印的。

問題2:返回

第9行沒有結(jié)束的原因是:

before_func()沒有返回值,默認(rèn)返回None.
所以if before_result != None是不成立的,會繼續(xù)往下執(zhí)行。

2018年3月8日 22:46
編輯回答
青裙

第一題
記住下面的語法,再加一點細(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.

2017年4月26日 07:41
編輯回答
咕嚕嚕

問題一:嵌套
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)致
2018年9月17日 02:41