Понимание поведения декоратора

Я хочу понять поведение декоратора в этом коде

abc.py

def my_decorator_module(some_function):
    def wrapper():
        num = 10
        if num == 10:
            print('yess')
        else:
            print('no')

        some_function()

        print('print after some_function() called')

    return wrapper()

и вызвать эту функцию в качестве декоратора

x.py

from abc import my_decorator_module

@my_decorator_module
def just_some_function():
    print("Wheee!")

вывод

yess
Wheee!
print after some_function() called

событие, которое я не назвал just_some_function() в файле x.py, когда я запускаю файл x.py, возвращаю вывод, почему?

2 ответа

Потому что ты звонил wrapper прежде чем вернуть его из вашей внешней функции украшения. Не делай этого.

return wrapper   # not wrapper()

В учебнике, который вы читаете, ранее была введена концепция возврата функций, а не их вызова и возврата их результатов; это то, что вам нужно делать здесь.

Вы не назвали явно just_some_function() но ваш "декоратор" делает, ср последнюю строку:

def my_decorator_module(some_function):
    def wrapper():
        num = 10
        if num == 10:
            print('yess')
        else:
            print('no')

        some_function()

        print('print after some_function() called')

    # here !!!   
    return wrapper()

На самом деле это ошибочная реализация - ваш декоратор не должен возвращать результат вызова wrapper, но вернуть wrapper сама функция:

    return wrapper

Если вы не понимаете, почему: @decorator синтаксис только синтаксический сахар, так что это:

@decorator
def somefunc():
    print("somefunc")

на самом деле только ярлык для этого:

def somefunc():
    print("somefunc")

somefunc = decorator(somefunc)

поэтому ваш декоратор должен возвращать объект функции (или любой вызываемый FWIW), обычно - но не обязательно - некоторую оболочку, которая позаботится о вызове декорированной функции (и предпочтительно о возвращении результата).

Другие вопросы по тегам