Как генераторы и сопрограммы реализованы в CPython? - программирование

Как генераторы и сопрограммы реализованы в CPython?

Я читал, что в CPython стеки интерпретатора (список функций Python, вызываемых для достижения этой точки) смешиваются с стеком C (список функций C, которые вызывались в собственном коде интерпретатора). Если да, то как реализуются генераторы и сопрограммы? Как они помнят свое состояние исполнения? CPython копирует каждый стек генератора/сопрограммы в стек и из стека ОС? Или CPython просто удерживает верхний стек стека генератора в куче, поскольку генератор может работать только с самого верхнего кадра?

4b9b3361

Ответ 1

Команда yield принимает текущий исполняемый контекст как замыкание и преобразует его в собственный объект жизни. Этот объект имеет метод __iter__, который будет продолжен после этой инструкции yield.

Таким образом, стек вызовов преобразуется в объект кучи.

Ответ 2

Понятие о том, что стек Python и стек C в запущенной программе Python смешиваются, может вводить в заблуждение.

Стек Python является чем-то полностью разделенным, чем фактический стек C, используемый интерпретатором. Структуры данных в стеке Python на самом деле являются полными "фреймовыми" объектами Python (которые даже могут быть интроспекрованы и иметь некоторые атрибуты, измененные во время выполнения). Этот стек управляется виртуальной машиной Python, которая сама запускается на C и, следовательно, имеет обычную C-программу, уровень машины, стек.

При использовании генераторов и итераторов интерпретатор просто сохраняет соответствующий объект фрейма где-то еще, чем в стеке программы Python, и отталкивает его туда, когда выполнение генератора возобновляется. Это "где-то еще" является самим объектом-генератором. Запуск метода "следующий" или "отправка" на объект-генератор вызывает это.

Ответ 3

Несколько существующих ответов и комментариев утверждают, что Python поддерживает "стек программ", который полностью отделен от стека VM C. Это утверждение неверно.

Проверьте ссылку: http://en.wikipedia.org/wiki/Stackless_Python

Stackless Python существует, но не является основным. Понимание - это правильный вопрос.