【问题标题】:Flow of python decorator functionspython装饰器函数的流程
【发布时间】:2015-09-17 12:46:39
【问题描述】:

我试图理解下面的例子,我发现解释decorators

#!/usr/bin/python

def get_text(name):
   return "lorem ipsum, {0} dolor sit amet".format(name)

def p_decorate(func):
    def func_wrapper(name):
        return "<p>{0}</p>".format(func(name))
    #return "1"
     return func_wrapper


get_text = p_decorate(get_text)

print get_text("John")

这个的输出是:

<p>lorem ipsum, John dolor sit amet</p>

我决定尝试更改此功能并将return func_wrapper 注释掉并替换为return "1"

当我这样做时,我得到了错误:

TypeError: 'str' object is not callable

我对此有 2 个问题:

  1. 当行

    print get_text("John") 
    

    被执行,是

    def func_wrapper(name):
    

    初始化为"John"?此行运行后的事件顺序是什么?

  2. 为什么我会收到这个错误,因为最后,string 最终还是不会被返回?

如果有人能用这段代码解释事件的流程,我将不胜感激。

【问题讨论】:

    标签: python decorator python-decorators


    【解决方案1】:

    只是为了补充。

    当你想在装饰器中传递参数时,你使用嵌套函数:

    def decorator(func):
        def wrapper(*args, **kwargs):
            print('My args:', *args, **kwargs)
            return func(*args, **kwargs)
        return wrapper
    

    所以你装饰:

    def my_function(*args, **kwargs):
        pass
    my_function = decorator(my_function)
    

    【讨论】:

      【解决方案2】:

      你在这里调用了装饰器:

      get_text = p_decorate(get_text)
      

      通常,装饰器将一个函数替换为另一个可调用函数(例如另一个函数),或者返回原始函数但已注册有关它的信息。

      但是通过将p_decorate() 的返回值更改为"1" 而不是函数包装器,您“破坏”了get_text,因为它现在不再是一个函数。不能像调用字符串那样调用字符串对象。

      之前,p_decorate() 返回了func_wrapper() 函数对象,所以get_text 被重新指向该函数。调用get_text('John') 确实调用了该嵌套函数。 func_wrapper() 然后确实以 'John' 作为参数调用,是的。函数毕竟只是对象,您可以将这些对象分配给您喜欢的任何有效 Python 名称。

      当调用func_wrapper() 时,它又调用func(),这是p_decorate() 的参数。同样,函数只是对象,因此调用了p_decorate(get_text)func 最终仍然绑定到原始的get_text 函数对象。调用 func() 调用原始函数。

      您可以在Python Tutor 中查看完整的通话流程。

      【讨论】:

      • 感谢 Martijn 的解释。 Python Tutor 很有帮助:)
      猜你喜欢
      • 2019-02-09
      • 2014-07-21
      • 2019-12-18
      • 2020-07-13
      • 2016-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-25
      相关资源
      最近更新 更多