Как лямбда-выражение может ссылаться на себя перед созданием экземпляра?Python

Программы на Python
Ответить
Anonymous
 Как лямбда-выражение может ссылаться на себя перед созданием экземпляра?

Сообщение Anonymous »

Ради шутки я попытался создать связанный список с лямбда-функциями. Я попробовал этот небольшой код в качестве первого шага, но мои эксперименты закончились после бесконечного цикла:

Код: Выделить всё

import itertools

stack = lambda: ("c", None)
stack = lambda: ("b", stack)
stack = lambda: ("a", stack)
for _ in itertools.count():
c, stack = stack()
print(c)
Ожидаемый результат:

Код: Выделить всё

a
b
c
TypeError: 'NoneType' object is not callable
Фактический результат:

Код: Выделить всё

a
a
a
...
Я ожидаю, что вторая лямбда будет содержать локальную (на вторую лямбду) ссылку на первую лямбду, а третья лямбда будет содержать локальную (на третью лямбду) ссылку на вторую лямбду.
Неожиданно третья лямбда возвращает ссылку на себя, что приводит к вечному циклу удаления стека для одной и той же лямбды. Этого не ожидалось, поскольку стек при создании лямбды указывает на предыдущую лямбду. Как лямбда может иметь ссылку на себя еще до создания?
Как мы видим в Python Tutor (постоянная ссылка на пример), каждая лямбда заменяется новой лямбдой, каждый раз ссылаясь на сам по себе (кроме первого, который возвращает None в качестве второго элемента кортежа):
Изображение

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

Код: Выделить всё

>>> def make_stack():
...     stack = lambda: ("c", None)
...     stack = lambda: ("b", stack)
...     stack = lambda: ("a", stack)
...     return stack
...
>>> stack = make_stack()
>>> stack.__closure__[0].cell_contents is stack
True
Как возможно, что лямбда-выражение имеет ссылку на себя, на еще даже не созданный объект?


Подробнее здесь: https://stackoverflow.com/questions/792 ... tanciation
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»