Как генераторы и сопрограммы реализованы в CPython? - PullRequest
46 голосов
/ 05 декабря 2011

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

Ответы [ 2 ]

46 голосов
/ 06 декабря 2011

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

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

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

16 голосов
/ 05 декабря 2011

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

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

...