[Python] Nested decorators with arguments in Python - call stack

Discussão em 'Python' iniciado por Stack, Agosto 16, 2025.

  1. Stack

    Stack Membro Participativo

    I am reading about Python decorators and I have stumbled upon example of nested decorators with arguments.

    I have tried to understand its call stack, but some steps seems to have no logic for me. Could someone please break down this call stack into little pieces for me?

    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() # <---


    And the output is:

    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


    My questions are:

    • Why after "real_decorator end" print, "log_before_and_after_wrapper start" print is executed?
    • Why run_only_between wrapper is called next?
    • Why then execution goes back to the log_before_and_after_wrapper

    I would be grateful for any help here.

    EDIT:

    Debug order

    Why after returning wrapper in real_decorator code jumps to @run_only_between and than to log_before_and_after()? Shouldn't wrapper() be executed since it was returned by real_decorator?

    Why after returning wrapper in log_before_and_after, say_something() is being executed and only after that code returns to wrapper in log_before_and_after?

    Continue reading...

Compartilhe esta Página