Лутц М. - Изучаем Python (1077325), страница 106
Текст из файла (страница 106)
Импортирование расширений, написанных на языке С, операция импорта в ануе)топ и импортирование пакетов — это расширенные возможности импортирования компонентов, не являющихся простыми файлами модулей. Впрочем, для импортера различия в типах загружаемых файлов совершенно незаметны как при импорте, так и при обращении к атрибутам модуля. Инструкция 1ерогт Ь загружает некоторый модуль Ь в соответствии с настройками пути поиска модулей, а Ь.
ат1г извлекает элемент модуля, будь то переменная или функция, написанная на языке С. Некоторые стандартные модули, которые мы будем использовать в этой книге, в действительности написаны на языке С, но благодаря прозрачности импортирования это не имеет никакого значения для клиентов. Если у вас в различных каталогах имеются файлы Ьру и Ь.зо, интерпретатор всегда будет загружать тот, что будет найден в каталоге, который располагается раньше (левее) в пути поиска модулей, так как поиск в списке ауа. ратп выполняется слева направо.
Но что произойдет, если оба файла, Ь.ру и Ь.зо, находятся в одном и этом же каталоге? В этом случае интерпретатор будет следовать стандартному порядку выбора файлов, впрочем, нет никаких гарантий, что такой порядок будет оставаться неизменным с течением времени. Вообще вы должны избегать зависимости от порядка выбора файлов интерпретатором Ру- 1)топ в одном и том же каталоге — давайте своим модулям различные имена или настраивайте путь поиска модулей, чтобы обеспечить более очевидный порядок выбора файлов.
Глава 18. Модули: общая картина 496 Дополнительные возможности выбора модуля Обычно операция импорта работает именно так, как описывается в данном разделе, — она отыскивает и загружает файлы, находящиеся на вашей машине. Однако вполне возможно переопределить большую часть того, что делает операция импорта, используя то, что называется лрограэтмньтми ловушками импорта. Эти ловушки могут использоваться, чтобы придать операции импорта дополнительные полезные возможности, такие как загрузка файлов из архивов, расшифровывание и т.
д. Фактически сам интерпретатор РутЬоп использует эти ловушки, чтобы обеспечить возможность извлечения импортируемых компонентов из Е1Р-архивов — заархивированные файлы автоматически извлекаются во время импорта, когда в пути поиска выбирается файл с расширением .гтр. За дополнительной информацией обращайтесь к описанию встроенной функции тьрогт в руководстве по стандартной библиотеке РутЬоп — настраиваемому инструменту, которым в действительности пользуется инструкция таро гт.
Кроме того, РуСЬоп поддерживает понятие файлов с оптимизированным байт-кодом (.руо), которые создаются и запускаются интерпретатором из командной строки с флагом -О, однако они выполняются лишь немногим быстрее, чем обычные файлы .рус (обычно на б процентов быстрее), поэтому они используются достаточно редко. Система Рзусо (глава 2) обеспечивает куда более существенный прирост в скорости выполнения. 2. Компиляция (если необходимо) После того как в пути поиска модулей будет найден файл, соответствующий имени в инструкции (зво гт, интерпретатор компилирует его в байткод, если это необходимо. (Мы рассматривали байт-код в главе 2.) Интерпретатор проверяет время создания файла и пропускает этап компиляции исходного программного кода, если файл с байт-кодом .рус не старше, чем соответствующий ему файл .ру с исходным текстом.
Кроме того, если РутЬоп обнаружит в пути поиска только файл с байт-кодом и не найдет файл с исходным текстом, он просто загрузит байт-код. Другими словами, этап компиляции пропускается, если можно ускорить запуск программы. Если вы измените исходный программный код, РутЬоп автоматически скомпилирует байт-код при следующем запуске программы. Кроме того, вы можете распространять свою программу исключительно в виде файлов с байт-кодом, чтобы не передавать файлы с исходными текстами.
Обратите внимание, что компиляция выполняется в момент импортирования файла. По этой причине файл .рус с байт-кодом для главного файла программы обычно не создается, если только он не был импортирован еще куда-нибудь, — файлы .рус создаются только при импортировании файлов. Байт-код главного файла программы создается в памяти компьютера, а байт-код импортированных файлов сохраняется в файлах для ускорения будущих операций импорта. 497 'как работает импорт Главные файлы программ часто планируется исполнять непосредственно и никуда их не импортировать.
Позднее мы увидим, что существует возможность создать файл, который будет играть роль как главного файла программы, так и модуля, доступного для импорта. Такие файлы могут и исполняться, и импортироваться, поэтому для них создаются соответствующие файлы .рус. Чтобы разобраться с тем, как это получается, читайте обсуждение специальных атрибутов паве и ватп в главе 21. 3. Запуск На последнем шаге операции импортирования производится запуск байт-кода модуля. Все инструкции в файле модуля выполняются по порядку, сверху вниз, и любые операции присваивания, которые встретятся на этом шаге, будут создавать атрибуты конечного объекта модуля. Таким образом, этот этап выполнения создает все инструменты, которые определяются модулем.
Например, во время импортирования выполняются инструкции бей в файле, которые создают функции и присваивают их атрибутам модуля. После этого функции могут вызываться из программы, выполнившей импорт. На этом последнем шаге операции импортирования фактически запускается программный код модуля, поэтому, если программный код верхнего уровня в файле модуля выполняет какие-нибудь действия, результаты этих действий можно будет наблюдать во время импорта.
Например, при импорте файла можно будет наблюдать результат работы инструкций рт1пт на верхнем уровне модуля. Инструкции Ьет просто определяют объекты для последующего использования. Как видите, во время импорта выполняется достаточно много работы— производится поиск файла, в случае необходимости запускается компилятор и производится запуск программного кода. Вследствие этого любой заданный модуль по умолчанию импортируется только один раз за все время работы программы. При повторных попытках импортировать модуль все три шага просто пропускаются, и повторно используется модуль, уже загруженный в память.' Если вам потребуется еще раз импортировать файл, который уже был загружен (например, чтобы обеспечить поддержку настроек, выполняемых пользователем), воспользуйтесь функцией ге1оад, с которой мы встретимся в следующей главе.
В реальности интерпретатор хранит загруженные модули во встроенном словаре зуз. воос1ез, который проверяется в начале операции импортирования, чтобы определить, не был лн уже загружен указанный модуль. Если вам потребуется увидеть, какие модули были загружены, импортируйте модуль зуз н выведите результат работы метода зуз. зосс1ез. кеуз ( ) . Подробнее об этой внутренней таблице рассказывается в главе 21. 498 Глава 18. Модули; общая картина Стороннее программное обеспечение: дЫи1В Настройка пути поиска модулей, описание которой приводится в этой главе, в первую очередь касается программного кода, который вы пишете самостоятельно.
Сторонние расширения для Ру1Ьоп обычно используют для автоматической установки самих себя такой инструмент, как Шзтст11з, входящий в состав стандартной библиотеки, поэтому для использования такого программного кода не требуется выполнять настройку пути поиска модулей. Системы, использующие стзтзт11з, обычно поставляются со сценарием зегир.ру, который запускается для установки таких систем — этот сценарий импортирует и использует модуль с1зтзт11з, чтобы поместить систему в каталог, который уже является частью пути поиска модулей (обычно в подкаталог ИЬ~зперас)гачев в каталоге, куда был установлен Ру(Ьоп). За дополнительной информацией о распространении и установке с помощью С(зтвт(1з обращайтесь к стандартному набору руководств по языку РуФЬоп, потому что эта тема далеко выходит за рамки данной книги (например, этот инструмент дополнительно обеспечивает возможность компиляции расширений на языке С на машине, где производится установка).
Кроме того, обратите внимание на развивающуюся систему еяяз, распространяемую с открытыми исходными текстами, которая добавляет возможность проверки зависимостей для установленного программного кода на языке Ру(Ьоп. В заключение В этой главе были даны основные понятия, имеющие отношение к модулям, атрибутам и импорту, а также был исследован принцип действия инструкции таро гт. Мы узнали, что во время операции импортирования производится поиск файла модуля в пути поиска модулей, компиляция в байт-код и выполнение всех инструкций, создающих его содержимое. Мы также узнали, как настроить путь поиска, в первую очередь с помощью переменной окружения РУТНОИРАТН, чтобы иметь возможность импортировать модули из других каталогов, отличных от домашнего каталога и от каталогов стандартной библиотеки.
Как показала эта глава, операция импортирования и модули являются основой архитектуры программ на языке Ру(Ьоп. Крупные программы делятся на множество файлов, которые связываются между собой во время выполнения посредством импортирования. Местонахождение файлов модулей во время импортирования определяется с по- 499 Закрепление пройденного мощью пути поиска модулей, а модули определяют атрибуты, использующиеся за пределами этих модулей. Конечно, основное назначение операции импорта и модулей состоит в том, чтобы образовать структуру программы, логика которой подразделяется на самостоятельные программные компоненты.
Программный код в одном модуле изолирован от программного кода в другом — фактически ни один модуль не может получить доступ к именам, определенным в другом модуле, если явно не выполнит инструкцию (арогг. Благодаря этому модули дают возможность минимизировать конфликты имен между различными частями программы.
В следующей главе вы увидите, что все это означает в терминах фактического программного кода. Но прежде чем двинуться дальше, постарайтесь ответить на контрольные вопросы к главе. Закрепление пройденного Контрольные вопросы 1. Каким образом файл с исходным программным кодом модуля превращается в объект модуля2 2. Зачем может потребоваться настраивать значение переменной окружения РТТНОйРАТН2 3. Назовите четыре основных компонента, составляющих путь поиска модулей. 4. Назовите четыре типа файлов, которые могут загружаться операцией импортирования.
5. Что такое пространство имен, и что содержит пространство имен модуляг Ответы 1. Файл с исходными текстами модуля автоматически превращается в объект модуля в результате выполнения операции импортирования. С технической точки зрения исходный программный код модуля выполняется во время импортирования, инструкция за инструкцией, и все имена, которым по мере выполнения операций будут присвоены значения, превращаются в атрибуты объекта модуля.