Python调用堆栈中带参数的嵌套装饰器
我正在阅读有关Python装饰器的文章,偶然发现了带有参数的嵌套装饰器示例。 我试图理解它的调用堆栈,但有些步骤对我来说似乎没有逻辑。有人能帮我把这个呼叫堆栈分解成小块吗Python调用堆栈中带参数的嵌套装饰器,python,python-decorators,Python,Python Decorators,我正在阅读有关Python装饰器的文章,偶然发现了带有参数的嵌套装饰器示例。 我试图理解它的调用堆栈,但有些步骤对我来说似乎没有逻辑。有人能帮我把这个呼叫堆栈分解成小块吗 from datetime import datetime def log_before_and_after(func): def wrapper(): print("log_before_and_after_wrapper start") result = fu
from datetime import datetime
def log_before_and_after(func):
def wrapper():
print("log_before_and_after_wrapper start")
result = func()
print("log_before_and_after_wrapper end")
return result
return wrapper
def run_only_between(_from=7, _to=22):
print("run_only_between start")
def real_decorator(func):
print("real_decorator start")
def wrapper():
print("run_only_between_wrapper start")
if _from <= datetime.now().hour < _to:
func()
print("run_only_between_wrapper end")
else:
print("run_only_between_wrapper end")
print("real_decorator end")
return wrapper
print("run_only_between end")
return real_decorator
@log_before_and_after
@run_only_between(7, 22)
def say_something():
print("Hello!!")
say_something() # <---
我的问题是:
为什么在执行“real\u decorator end”
打印之后、“log\u before\u和\u after\u wrapper start”
打印
为什么下一步调用包装器之间的run\u only\u
那么为什么exexution返回到包装器之前和之后的log\u
如果能在这里得到任何帮助,我将不胜感激
编辑:
为什么在real\u decorator
code中返回wrapper
后,代码会在和之间跳到@run\u only\u,而不是在之前和之后()记录?由于它是由real\u decorator
返回的,所以不应该执行wrapper()
为什么在log\u before\u和\u after
中返回wrapper
后,say\u something()
会被执行,并且只有在log\u before\u和\u after
中返回wrapper
后,代码才会被执行?我认为如果您在调试模式下运行代码,并逐步执行代码,您的工作会更轻松。然后您可以看到代码是如何跳转的。前两个方法是方法定义。那里还没有采取任何行动。您的第三个方法是一个方法定义,但它正在被修饰。这是你的第一张照片。(方法尚未执行!)即使在run\u中没有执行所有打印命令,也只执行之间的命令。只返回外部打印和新的装饰方法等。这很难用语言表达。@Tin Nguyen使用调试器是我脑海中第一件想到的事情,这就是我为什么发布这个问题的原因。代码之间的一些“跳跃”对我来说是完全不清楚的。如果有人能一步一步地向我解释调用堆栈,那就太神奇了。我知道有很多跳跃。我明白为什么会发生这些跳跃。在调试模式下运行时,如果指出一些不理解和看不到的跳转,会更容易。我会解释那些具体的跳跃。但是我不会解释所有的跳转,因为这个解释太复杂和混乱了。@TinNguyen我已经上传了调试执行顺序并添加了我的问题,你能看一下吗?我不知道如何更直观地解释它。如果你只看一个装饰师,你会更容易理解它。
run_only_between start
run_only_between end
real_decorator start
real_decorator end
log_before_and_after_wrapper start
run_only_between_wrapper start
Hello!!
run_only_between_wrapper end
log_before_and_after_wrapper end