【发布时间】:2023-03-04 13:24:02
【问题描述】:
玩装饰器,发现一些奇怪的东西:我有一些简单的东西如下(一个装饰器将函数注册到列表中:
stored_f = []
def register(f):
stored_f.append(f.__name__)
return f
@register
def say_hello(name):
print(f"Hello {name}")
@register
def ur_awesome(name):
return f"{name}, you are awesome!"
我以为上面的代码什么都不会做(它什么都不会打印出来),因为我没有执行任何东西,但实际上一个打印命令“print(stored_f)”会有一个输出:
['say_hello', 'ur_awesome']
意思是 register() 中的“stored_f.append(f.__name__)”行实际上被执行了两次。这对我来说很奇怪。
我尝试像往常一样在寄存器中定义一个 wrapper(),然后返回 wrapper,问题就会消失。但是我还是不明白为什么上面的代码会部分执行装饰器而不调用它。
【问题讨论】:
-
你为什么认为不会被处决?它不会“不调用就部分执行装饰器”;它完全通过调用装饰器来执行它。
-
“因为我没有执行任何操作” - 但
@register执行register。 -
@jonrsharpe 因为我没有执行任何东西,所以它只是所有定义。就像我最后说的,如果我在寄存器中放一个包装器,它绝对不会像我预期的那样做任何事情。
-
“如果我在寄存器中放一个包装器,它绝对不会像我预期的那样做任何事情” - 因为你执行了
register,而不是包装器。 -
register的主体被执行。你在里面做什么都会做。如果您更改register的定义,以便不附加到其中的stored_f,那么是的,它仍然是空的。装饰器语法基本上是say_hello = register(say_hello)的简写。