我有代码:
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
有两个值?
答案 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
,因为它仍然可用。