请教Python装饰器@嵌套顺序的问题

发布于 2022-09-06 16:04:20 字数 1787 浏览 26 评论 0

请教大家两个Python装饰器@的问题。

问题一:嵌套。

1 def Decorator2(plugger2):
2      plugger2()
3      print ("Plugger2 内调 here!")
4 def Decorator3(plugger3):
5      plugger3()
6      print ("Plugger3 内调 here!")

7 def DecoratorTesting():
8      @Decorator2
9      def plugger2():
10          print ("Plugger2 外调 here!")
11          @Decorator3
12          def plugger3():
13                print ("Plugger3 外调 here!")

最终运行DecoratorTesting()结果是:

Plugger2 外调 here!
Plugger3 外调 here!
Plugger3 内调 here!
Plugger2 内调 here!

我对DecoratorTesting()这个结果不太理解。当第8行@Decorator2的时候,难道不是应该立即回到第1行打印“内调”吗?当第11行@Decorator3的时候,难道不是应该立即回到第4行打印“内调”吗?为什么结果却是刚才的顺序呢?

问题二:返回。

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.")

最终运行go_Middle('@', '#')结果是:

Go to the before yields @@.
Go to the middle.
Go to the after yields ###.

我对go_Middle()这个结果不太理解。第9行,应该已经彻底返回了。可是为什么还会继续执行第10行和以后的部分呢?

谢谢了先!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

等待圉鍢 2022-09-13 16:04:20

问题1:DecoratorTesting()的执行顺序

#先执行@Decorator2装饰的装饰函数plugger2()

@Decorator2
def plugger2():
    ...

#等同于下面:

Decorator2(plugger2)

#即按照下面的流程来执行,下面也是这个函数的整体流程,即先执行plugger2(),最后再打印"plugger2内调"
#再好好分析一下,下面这个流程就是这个函数执行的流程,这里要弄明白。

plugger2()
print("Plugger2 内调 here!") #P4

这里就是你疑惑的关键点之一,实际上你明白了上面函数的执行流程,你也就明白了为什么"plugger2内调会最后打印了"

无论如何,print("Plugger2 内调 here!")会在plugger2()函数执行完成之后再执行,所以它一定会是最后执行的语句

然后我们看plugger()函数是怎么执行的:

9      def plugger2():
10          print ("Plugger2 外调 here!") #P1
11          @Decorator3
12          def plugger3():
13                print ("Plugger3 外调 here!")

#############################################

# 首先执行print ("Plugger2 外调 here!"),这也是整个函数最先执行的一个print语句

# 然后plugger2里面又嵌套了一个装饰器,按照上面的分析方式再来一次
Decorator3(plugger3)
    ||
    ||
    \/
plugger3() # P2
print ("Plugger3 内调 here!") #P3

到了这里所有print顺序都已经理清楚了。按照我标注的P1--P4的顺序打印的。

问题2:返回

第9行没有结束的原因是:

before_func()没有返回值,默认返回None.
所以if before_result != None是不成立的,会继续往下执行。

蘑菇王子 2022-09-13 16:04:20

问题一:嵌套
def Decorator2(plugger2):

  plugger2()
  print ("Plugger2 内调 here!")
  

@Decorator2
def plugger2():

 print ("Plugger2 外调 here!")
 @Decorator3
 def plugger3():
     print ("Plugger3 外调 here!")

当你使用装饰器的时候等同用把下面的def 传给了你装饰器里面的形参 plugger2, plugger3 这是装饰器里面运行形参这个def 代码从上至下所以会限制性形参所指向的def运行这是就先出来外调 内部装饰器同样的道理

问题二:返回

这个问题由于你 before_result = before_func(request, follow_up) 这个时候已经调用了函数,函数没有返回值 导致
同展鸳鸯锦 2022-09-13 16:04:20

第一题
记住下面的语法,再加一点细心便可理解

# 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 ,可以转变成

def DecoratorTesting():
    def plugger2():
        print("Plugger2 外调 here!")
        def plugger3():
            print("Plugger3 外调 here!")
        plugger3 = Decorator3(plugger3)
    plugger2 = Decorator2(plugger2)

第二题

我对go_Middle()这个结果不太理解。第9行,应该已经彻底返回了。可是为什么还会继续执行第10行和以后的部分呢?

其实第 9 行的条件并不成立

9                 if (before_result != None):  return before_result;

因为 go_Before 没有显式 return 语句, 默认返回 None.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文