Виртуальная машина Python является стек на основе. Ссылки на объекты Python помещаются в стек, а код операции выталкивает одно или несколько из них, выполняет некоторую операцию и обычно возвращает результат обратно в стек для использования следующим кодом операции.
В качестве альтернативы вам может понадобиться разобрать простой арифметический расчет (операции должны быть полностью переупорядочены для работы в этом формате). Или прочитайте на FORTH; Python VM не отличается от FORTH, но фактический язык FORTH отражает его виртуальную машину таким образом, что Python этого не делает. В любом случае, с объяснением ...
Код операции LOAD_NAME
получает ссылку на объект os
. (Это, случается, модуль, но неважно, какой он объект, он работает одинаково со всеми видами объектов.) Ссылка помещается поверх стека.
(Это не поиск или загрузить модуль. Python уже импортировал ссылку на os
с предыдущим import
заявлением, и только получением этой ссылки из глобальных переменных.)
LOAD_ATTR
опкода получает ссылка на объект listdir
любого объекта, на который ссылается в верхней части стека. (Опять же, эта ссылка является функцией, но это не имеет значения.) Ссылка на объект в верхней части стека выталкивается и результат LOAD_ATTR
нажимается.
Код операции LOAD_CONST
получает ссылку на строку '.'
и толкает ее поверх стека.
Теперь CALL_FUNCTION
выскакивает 1 ссылка со стека. Это ссылка на строку '.'
, аргумент os.listdir
. (Он знает, чтобы поместить 1 ссылку, потому что операнд CALL_FUNCTION
равен 1. Если функция приняла больше аргументов, было бы более LOAD
опкодов, и операнд кода операции CALL_FUNCTION
был бы выше.) Он выталкивает другую ссылку из стека, которая ссылка на функцию os.listdir
. Затем он вызывает функцию с аргументами. Возвращаемое значение функции затем помещается в стек, где его можно использовать дополнительными кодами операций.
Как вы обнаружили, имена os
и listdir
хранятся в таблице co_names
. Операнды в коды LOAD_NAME
и LOAD_ATTR
являются индексами в этой таблице.Аналогично обрабатывается '.'
, за исключением того, что он хранится в таблице co_consts
.
поэтому команда 'IMPORT_NAME' ищет файл' os.pyc'? модуль идентифицируется только по имени? также как python знает положение байт-кода функции listdir в файле 'os.pyc'? – Kikapi
Нет, как я объяснил, 'IMPORT_NAME' ищет' os' в глобальных переменных. Он существует, потому что он был ранее импортирован с помощью оператора import. Способ, которым Python знает расположение функции 'listdir', заключается в том, что он находится в пространстве имен модуля' os', т. Е. Глобальных переменных этого модуля. – kindall
«просто извлекает эту ссылку из глобальных переменных» - технически она проверяет области поиска http://stackoverflow.com/questions/291978/short-description-of-python-scoping-rules, и в этом случае она находит ее в глобальный охват. –