Функциональные декораторы в Python - PullRequest
1 голос
/ 01 апреля 2020

Я новичок в python и пытаюсь обернуть голову вокруг функциональных декораторов в python. И я не могу понять, как функции возвращают функции.

Я имею в виду, в каком порядке интерпретатор интерпретирует эту функцию:

def decorator(another_func):
    def wrapper():
        print('before actual function')
        return another_func()
    print('pos')
    return wrapper

И в чем разница между этими двумя операторами: -

return wrapper

И

return wrapper()

Я использую Head First Python, но эта топика c Мне кажется, там не очень хорошо описано, пожалуйста, предложите любое видео или хороший ресурс, чтобы что я могу это понять.

Ответы [ 2 ]

3 голосов
/ 01 апреля 2020

Ключом к пониманию разницы является понимание того, что все является объектом в python, включая функции. Когда вы используете имя функции без скобок (return wrapper), вы возвращаете саму функцию. Когда вы используете круглые скобки, вы вызываете функцию. Взгляните на следующий пример кода:

def foo(arg):
    return 2

bar = foo
baz = foo()
qux = bar()
bar()

Если вы напечатаете baz или qux, он напечатает два. Если вы напечатаете bar, он даст вам адрес памяти для ссылки на функцию, а не число. Но если вы вызываете функцию, вы теперь печатаете результаты th

2 голосов
/ 01 апреля 2020

Я не могу понять, как функции возвращают функции.

Как уже объяснено LTheriault, в python все является объектом. Не только это, но и все происходит во время выполнения - оператор def является исполняемым оператором, который создает объект function из кода в блоке def и связывает этот объект с именем функции в текущем пространстве имен - IOW - это, в основном, syntacti c sugar для некоторых операций, которые вы можете кодировать вручную (хотя очень приветствуется syntacti c sugar - создание функционального объекта "вручную" - довольно большая работа).

Обратите внимание, что наличие функций «первоклассных граждан» - это не Python специфика c - это основа функционального программирования .

Я имею в виду, в каком порядке интерпретатор интерпретирует эту функцию:

def decorator(another_func):
    def wrapper():
        print('before actual function')
        return another_func()
    print('pos')
    return wrapper

Предполагается, что функция decorator объявлена ​​на верхнем уровне модуля: сначала выполняется среда выполнения берет блок кода, следующий за оператором def, компилирует его в объект code, создает объект function (экземпляр типа 'function') из этого объекта code и пару других вещей (список аргументов) et c) и, наконец, привязывает этот объект функции к объявленному имени (nb: 'binds' => "assignments").

Внутренний оператор def фактически выполняется только тогда, когда внешняя функция вызывается и выполняется заново каждый раз, когда вызывается внешняя функция - IOW, каждый вызов decorator возвращает новый экземпляр функции.

Приведенное выше объяснение, конечно, довольно упрощено (следовательно, частично неточно), но достаточно понять принцип базового c.

...