-1

我有代码:

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函数的打印。然后,在#2wrapper()中调用来自函数的引用。所以在这个调用之后,wrapperreference 将运行print('..')set 本身的函数,并返回之前存储在其中的值('嗨。我是目标。',如开头所述)。那么,wrapper函数stores有两个值吗?

4

2 回答 2

4

包装器只存储要调用的函数。它打印,然后调用函数并返回函数的返回值。无论函数做什么都与它无关。

于 2013-09-28T00:56:45.430 回答
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"

请注意,当装饰器应用于目标函数时会打印“In the decorator”,而不是稍后调用装饰函数时。如果需要,您仍然可以调用原始函数my_target,因为它仍然可用。

于 2013-09-28T01:48:05.830 回答