简体   繁体   English

python装饰器功能的流程

[英]Flow of python decorator functions

I'm trying to understand the following example I found explaining 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")

The output of this is: 这个输出是:

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

I decided to try and change this function up and commented out return func_wrapper and replaced it with return "1" . 我决定尝试更改此功能并注释掉return func_wrapper并将其替换为return "1"

When I do this, I get the error: 当我这样做时,我收到错误:

TypeError: 'str' object is not callable

I have 2 questions regarding this: 我有两个问题:

  1. When the line 当行

     print get_text("John") 

    is executed, is 执行,是

     def func_wrapper(name): 

    initialised with "John" ? "John"初始化? What is the sequence of events after this line is run? 运行此行后的事件顺序是什么?

  2. Why am I getting this error, because in the end, isn't a string ultimately being returned anyway? 为什么我会收到此错误,因为最终,最终是不是最终返回的string

If anyone could explain the flow of events with this code, I would greatly appreciate it. 如果有人能用这段代码解释事件的流程,我将非常感激。

You called the decorator here: 你在这里打电话给装饰者:

get_text = p_decorate(get_text)

Normally, a decorator replaces a function with another callable (another function, for example), or returns the original function but having registered information about it. 通常,装饰器将函数替换为另一个可调用函数(例如,另一个函数),或返回原始函数但已注册有关它的信息。

But by changing the return value of p_decorate() to "1" rather than the function wrapper, you 'broke' get_text as that is no longer a function now. 但是通过将p_decorate()的返回值更改为"1"而不是函数包装器,你'打破了' get_text因为它现在不再是一个函数。 You cannot call a string object like you could call a string. 你不能像调用字符串一样调用字符串对象。

Before, p_decorate() returned the func_wrapper() function object, so get_text was rebound to point to that function. 之前, p_decorate()返回了func_wrapper()函数对象,因此get_text被反弹以指向该函数。 Calling get_text('John') really called that nested function. 调用get_text('John')确实调用了嵌套函数。 func_wrapper() is then indeed called with 'John' as the argument, yes. 然后确实用'John'作为参数调用func_wrapper() ,是的。 Functions are after all just objects, you can assign those objects to any valid Python name you like. 函数毕竟只是对象,您可以将这些对象分配给您喜欢的任何有效Python名称。

When func_wrapper() is called, it in turn calls func() , which was the argument to p_decorate() . func_wrapper()时,它又调用func() ,这是p_decorate()的参数。 Again, functions are just objects , so having called p_decorate(get_text) , func ends up still bound to the original get_text function object. 同样,函数只是对象 ,因此调用了p_decorate(get_text)func最终仍然绑定到原始的get_text函数对象。 Calling func() calls that original function. 调用func()调用原始函数。

You can see the full flow of the calls in Python Tutor . 您可以在Python Tutor中看到完整的调用流程。

Just to complement. 只是为了补充。

You use nested functions when you want to pass args inside decorator: 当你想在decorator中传递args时,你使用嵌套函数:

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

So you decorate: 所以你装饰:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM