Код: Выделить всё
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
Мобильная версия