2016-02-17 3 views
2

Я пытаюсь понять процесс вызова функции питона, я создал простой .pyc файл, который вызывает os.listdir('.'), я увидел, что os и listdir сохраняются в co_names таблицы, при выполнении CALL_FUNCTION байткода инструкции, как идентифицируется библиотека os? это его имя, используя таблицу co_names? python начинает поиск модуля с именем os.pyc? если да, то как знает python, где находится смещение байт-кода функции, вызванной в модуле .pyc?Процесс вызова функции библиотеки питона

Спасибо.

Дис модуль байткодом сниппет

5   28 LOAD_NAME    0 (os) 
      31 LOAD_ATTR    2 (listdir) 
      34 LOAD_CONST    3 ('.') 
      37 CALL_FUNCTION   1 

ответ

4

Виртуальная машина 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.

+0

поэтому команда 'IMPORT_NAME' ищет файл' os.pyc'? модуль идентифицируется только по имени? также как python знает положение байт-кода функции listdir в файле 'os.pyc'? – Kikapi

+0

Нет, как я объяснил, 'IMPORT_NAME' ищет' os' в глобальных переменных. Он существует, потому что он был ранее импортирован с помощью оператора import. Способ, которым Python знает расположение функции 'listdir', заключается в том, что он находится в пространстве имен модуля' os', т. Е. Глобальных переменных этого модуля. – kindall

+1

«просто извлекает эту ссылку из глобальных переменных» - технически она проверяет области поиска http://stackoverflow.com/questions/291978/short-description-of-python-scoping-rules, и в этом случае она находит ее в глобальный охват. –

Смежные вопросы