Магия замыкания в функциях высшего порядка. - PullRequest
0 голосов
/ 28 мая 2018

Легко узнать, как назначить глобальную переменную внутренней функции - что сделает глобальную переменную самой функцией, равной внутренней функции - но как интерпретатор узнает, как вызвать аргумент из внутренней функции с помощьюиспользуя код ниже?

def outer(arg):
    def inner(arg2):
        print(arg, ',', arg2):
    return inner

a = outer(‘outer arg’)

print(a) # .inner at 0x109bd0048
a('inner arg') # Output: outer arg, inner arg

Делая print(a), мы видим, что переменная / функция a становится внутренней функцией.

Что я не понимаю, так это то, как присвоение переменной a внешней функции предназначается для внутренней функции и аргумента с кодом, a(‘inner argument’))

Это как-то неявно вызываетвнутренняя функция без явного указания?

Делает ли это что-то вроде этого:

a = outer('outer arg')inner('inner arg')

Где находится исходный код python за этой магией?

1 Ответ

0 голосов
/ 28 мая 2018

Мне не хватает репутации для комментария, поэтому я должен написать ответ ...

Из превосходного "Свободного питона" Лучано Рамальо:

"... Python хранит имена локальных и свободных переменных в атрибуте __code__, который представляет скомпилированное тело функции"

"Подводя итог: замыкание - это функция, которая сохраняет привязки свободных переменных, которыесуществуют, когда функция определена, так что их можно использовать позже, когда функция вызывается и определяющая область больше не доступна "

Я добавил пару строк в ваш код, чтобы визуализировать это:

def outer(arg):
    def inner(arg2):
        print(arg, ',', arg2)
    print (inner.__code__.co_freevars)
    print (inner.__closure__[0].cell_contents)
    return inner

Что выводит следующее:

In [169]: outer('outer arg')
('arg',)
outer arg

Таким образом, как вы можете видеть, значение arg сохраняется даже после того, как функция вышла из области видимости, поскольку она является свободной переменной,Привязка для arg хранится в атрибуте __closure__.

Это только подсказка для дальнейшего чтения, я ни в коем случае не эксперт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...