python装饰器功能的流程

时间:2015-06-30 15:58:27

标签: python decorator python-decorators

我正在尝试理解以下示例,我发现了解释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

我有两个问题:

  1. 当行

    print get_text("John") 
    

    执行,是

    def func_wrapper(name):
    

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

  2. 为什么我会收到此错误,因为最终,最终还是不会返回string

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

2 个答案:

答案 0 :(得分: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中看到完整的来电。

答案 1 :(得分:1)

只是为了补充。

当你想在decorator中传递args时使用嵌套函数:

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)