装饰器是否存储了多个返回值?

时间:2013-09-27 23:22:11

标签: python function

我有代码:

def my_decorator(target):
    def wrapper():
        print('Calling function "%s"' % target.__name__)
        return target() # 1
    return wrapper # 2
@my_decorator
def my_target(): # 3
    print('Hi. I am the target.')
my_target()

我将描述我对这种模式无序的理解。

#3我们将函数my_target作为参数传递给装饰器my_decorator。没问题。

#1实际上我们正在调用函数my_target

#2(我怀疑)。当我们在#1中调用该函数时,它将打印并返回wrapper 'Hi. I am the target.',因此wrapper现在存储来自my_target函数的打印。然后,在#2中调用来自wrapper()函数的引用。因此,在此调用之后,wrapper引用将运行print('..')自身集合函数,并将返回之前存储的值('嗨。我是目标。',如开头所述)。那么,wrapper函数stores有两个值?

2 个答案:

答案 0 :(得分:4)

包装器只存储要调用的函数。它打印,然后调用函数并返回函数的返回值。无论功能如何,都不是它的业务。

答案 1 :(得分:3)

您可以尝试在不使用@decorator语法的情况下解压缩示例。首先,让我们了解@decorator的作用。声明:

@decorator
def func():
    pass

相当于:

def func():
    pass
func = decorator(func)

为了便于理解,我建议您手动执行此操作,但为功能的装饰版本选择其他名称:

def decorator(target):
    print("In the decorator")
    def wrapper():
        print("In the wrapper")
        target()
    return wrapper

def my_target():
    print("In the target")

my_decorated_target = decorator(my_target) # this will print "In the decorator"

my_decorated_target() # prints "In the wrapper" then "In the target"

请注意,当装饰器应用于目标函数时,将打印“在装饰器中”,而不是在稍后调用装饰函数时。如果您愿意,您还可以调用原始函数my_target,因为它仍然可用。