2013-08-14 2 views
4

У меня есть это:Адрес лямбда-функции в Python

>>> a = lambda : lambda x : x * x 

Это дает мне постоянные адреса при каждом:

>>> a 
<function <lambda> at 0x7f22769e76e0> 
>>> a 
<function <lambda> at 0x7f22769e76e0> 
>>> a 
<function <lambda> at 0x7f22769e76e0> 

Однако это не делает. Почему так? Также обратите внимание, что это дает только два адреса? Почему так? Является ли внутренняя лямбда-функция создаваемой на лету и возвращается каждый раз при вызове a()? Разве это не было создано, когда было объявлено?

>>> a() 
<function <lambda> at 0x7f22769e7320> 
>>> a() 
<function <lambda> at 0x7f22769e75f0> 
>>> a() 
<function <lambda> at 0x7f22769e7320> 
>>> a() 
<function <lambda> at 0x7f22769e75f0> 
+2

Я предполагаю, что часть двух адресов связана с специальной переменной '_', созданной для хранения результата предыдущего вычисления в интерактивном сеансе. Поскольку есть ссылка на него, возвращаемое значение (которое вы видите 'repr' of) получает только мусор, собранный после выполнения второго оператора (заменяя ссылку в' _'). В неинтерактивном скрипте вы можете получить один и тот же адрес для всех из них (хотя, вероятно, это не тот же объект, а просто повторно используемая память). – Blckknght

+0

@Blckknght Вы правы - я протестировал его, и в скрипте адрес тот же, хотя я все еще очень смущен о том, почему. Можете ли вы предоставить ссылку с дополнительной информацией или дать более подробный ответ? –

+2

Интересно, 'print a()' не имеет такого же поведения – Aert

ответ

1

Да, ваше понимание правильно: «внутренняя» лямбда создается только тогда, когда «внешняя» лямбда оцениваются, что не произойдет, пока он (внешний) не вызывается.

+0

Это не имеет никакого отношения к тому, что Python является интерпретированным языком. Внутренняя лямбда также должна быть создана только тогда, когда внешний объект оценивается на скомпилированном языке. –

+0

Хорошо, я уточню свой ответ, чтобы убедиться, что нет дезинформации. В случае лямбды скомпилированный язык, вероятно, будет действовать одинаково, но OP, похоже, работает над тем, что python каким-то образом оценит определение функции 'a' до ее фактического выполнения. Скомпилированный язык будет иметь этот вариант, но, скорее всего, не будет действовать на нем для лямбды. Он может делать это для других вещей, таких как буквальные арифметические выражения или разрешение адреса времени компиляции, тогда как строго интерпретируемый язык даже не имеет возможности. – brianmearns

2

a является самой функцией как переменной. Его адрес не изменится, если он не будет каким-то образом перемещен в памяти.

a() фактически вызывает функцию. Функция ничего не сделает, пока не будет вызвана через (). Так что да, здесь ваша внутренняя лямбда-функция создается на лету. Это будут адреса, которые вы видите там. Как комментирует Blckknght, сборка мусора, вероятно, приводит к повторному использованию памяти.

Смежные вопросы