Лутц М. - Изучаем Python (1077325), страница 112
Текст из файла (страница 112)
Пакеты модулей Файлы (пй,ру могут содержать программный код на языке Ру$Ьоп, как любые другие файлы модулей. Отчасти они являются объявлениями для интерпретатора и могут вообще ничего не содержать. Эти файлы, будучи объявлениями, предотвращают неумышленное сокрытие в каталогах с совпадающими именами истинно требуемых модулей, если они отображаются позже в списке путей поиска модулей.
Без этого защитного механизма интерпретатор мог бы выбирать каталоги, которые не имеют никакого отношения к вашему программному коду, только лишь потому, что в пути поиска они появляются ранее. В общем случае файл (пй .ру предназначен для выполнения действий по инициализации пакета, создания пространства имен для каталога и реализации поведения инструкций ггоз ° (тоесть Ггоа ... 1зро гг *), когда они используются для импортирования каталогов: Инициализация пакета Когда интерпретатор Ру1Ьоп импортирует каталог в первый раз, он автоматически запускает программный код файла (п(г .ру этого каталога. По этой причине обычно в эти файлы помещается программный код, выполняющий действия по инициализации, необходимые для файлов в пакете. Например, этот файл инициализации в пакете может использоваться для создания файлов с данными, открытия соединения с базой данных и т.д.
Обычно файлы (п(г .ру не предназначены для непосредственного выполнения— онн запускаются автоматически, когда выполняется первое обращение к пакету. Инициализация пространства имен модуля При импортировании пакетов пути к каталогам в вашем сценарии после завершения операции импортирования превращаются в настоящие иерархии вложенных объектов. Например, в предыдущем примере после завершения операции импортирования можно будет использовать выражение О(г1.
О1г2, которое возвращает объект модуля, чье пространство имен содержит все имена, определяемые файлом 1п(1 .ру из каталога Жг2. Такие файлы создают пространства имен для объектов модулей, соответствующих каталогам, в которых отсутствуют настоящие файлы модулей. Поведение инструкции г гон * В качестве дополнительной особенности, в файлах )пц,ру можно использовать списки а11, чтобы определить, что будет импортироваться из каталога инструкцией Ггоэ *. (Мы познакомимся со списком а11 в главе 21.) Список а11 в файлах (п(г .ру представляет собой список имен субмодулей, которые должны импортироваться, когда в инструкции Г гол * указывается имя пакета (каталога). Если список а11 отсутствует„инструкция г гол * не будет автоматически загружать субмодули, вложенные в каталог,— она загрузит только имена, определяемые инструкциями присваивания в файле (п(г .ру, включая любые субмодули, явно импор- 525 Пример импортирования пакета тируемые программным кодом в этом файле.
Например, инструкция тгсв аоЬвобо1е !врет! Х в файле т1! .ру создаст имя Х в пространстве имен каталога. Эти файлы можно оставить пустыми, если вам не требуется выполнять специальных действий. Однако для успешного выполнения операции импортирования каталогов они должны существовать обязательно. Пример импортирования пакета Рассмотрим практический пример программного кода, который де- монстрирует„как используются файлы инициализации и пути к ката- логам.
Следующие три файла располагаются в каталоге г(!и! и в подка- талоге д!гл: а Файл: бтг1чч гп!т РУ ргтпт 'бгг1 тшт' к=1 а файл: бтг11бтг21 тп!т .ру рг!пт 'бтг2 тот!' у = 2 № файл; б!г11бтг21воб.ру рг1пт 'тп воб.ру' з = 3 В данном случае каталог г(!г1 может быть подкаталогом нашего рабочего каталога (то есть домашнего каталога программы) или подкаталогом одного из каталогов, перечисленных в пути поиска модулей (с точки зрения реализации: каталога, входящего в список эуа. рата). В любом из этих случаев для каталога, вмещающего подкаталог с(!т1, не требуется наличие файла !л!1 чру. Инструкции !врог! выполняют файл инициализации в каждом каталоге, который присутствует в пути к модулю, — инструкции р г!пт, присутствующие в этих файлах„позволят отследить их выполнение.
Кроме того, как и файлы модулей, уже импортированные каталоги могут передаваться функции ге1оаб для принудительного повторного исполнения этого единственного элемента. Как показано ниже, для повторной загрузки каталогов и файлов функция ге1оаб также может принимать цепочку имен, разделенных точками: % рутйоп »> 1врогт б1г1.б1г2.воб бтг1 !п11 б!г2 1птт 1п воб.ру »> »> 1врогт б1г1.б1г2.воб >» »> ге1оаб(б1г1) № Сначала запускаются файлы инициализации № Лоатсрное иипортироеание не аыполняется Глава 20.
Пакеты модулей 526 Отг! >птт <вобо1е 'Отг!' Ггов 'О1г!'х тп!1 ,рус'> »> »> ге1оаб(О1г!.О1г2) б1г2 1п11 <вобо1е 'б1г!.О1г2' Ггов 'О!г!'Хбтг2! !п11 рус'> После операции импортирования путь, указанный в инструкции шрот!, становится цепочкой вложенных объектов. Здесь воб — это объект, вложенный в объект О1г2, который в свою очередь вложен в объект б! г1: »> б1г! <вобо1е 'О!г!' Ггов Отг!'! 1п11 рус'> »> О1г!.б1г2 <вобо1е 'Отг!.О1г2' ггов 'Отг!1Отг2<, тптт .рус'> »> б1г!.б1г2.воб <вобо1е 'Отг!.О!г2 воб' ггов 'О1г!<О1<2твоб.рус'> Каждый каталог в пути фактически становится переменной„которой присваивается объект модуля, пространство имен которого инициализируетея всеми инструкциями присваивания в файле 1п11 .ру, находящемся в этом каталоге.
Имя Отг!. х ссылается на переменную х, которой присваивается значение в файле <11г1<т 1п11 .ру, точно так же, как имя воб, 2 ссылается на переменную г, которой присваивается значение в файле тот)рбд »> б1г!.х ! »> б1гтлпг2.у г »> б1г!.О1г2.воб.а 3 Инструкции угой и ппрогт для пакетов Использование инструкции !врет! может оказатьея несколько неудобным для импортирования пакетов, потому что в этом случае далее в программе вам придется часто вводить полные пути для обращения к именам.
В примере из предыдущего раздела, например, приходилось каждый раз вводить полный путь от О1г 1, когда необходимо было обратиться к переменной 2. Если попытаться непосредственно обратиться к б! г2 или воб, будет получено сообщение об ошибке: »> б1г2.воб ИавеЕггог: паве 'О1г2' !а пот Оет1пеб »> воб.г ИавеЕггог: паве 'воб' та пот Оет!пеб Поэтому для импортирования пакетов часто более удобно использовать инструкцию ггов, чтобы избежать необходимости ввода полного имени при каждом обращении к нему.
Пожалуй, еще более важно, что 527 Зачем используется операция импортирования пакетов? если вы когда-нибудь выполните реструктуризацию дерева каталогов, то в случае использования инструкции !гоа достаточно будет обновить только саму инструкцию, тогда как в случае использования инструкции !арогс придется обновлять все обращения к именам в изменившемся пакете. Расширение гарогс ав, обсуждаемое в следующей главе, поможет вам определить сокращенные синонимы для полных путей: В указывать полный путь не требуется В Использование короткого синонима Зачем используется операция импортирования пакетов? Если вы только начинаете осваивать язык РуСЬоп, то прежде чем переходить к использованию пакетов, вам сначала необходимо освоить работу с простыми модулями.
Пакеты действительно являются полезным инструментом, особенно в крупных программах: они делают операцию импортирования более информативной, выступают в роли организационного инструмента, упрощают поиск файлов модулей и способны разрешать возникающие неоднозначности. Так как операция импортирования пакетов содержит некоторые сведения о структуре каталогов, где находятся файлы программы, они, в первую очередь, упрощают поиск файлов и служат организационным инструментом. Не имея информации о путях к пакетам, вам часто пришлось бы обращаться к содержимому пути поиска модулей, чтобы отыскать требуемые файлы. Кроме того, если вы организовали размещение своих файлов в дереве каталогов по функциональным признакам, то операция импортирования пакетов делает более очевидной роль, которую играют пакеты, что обеспечивает более высокую удобочитаемость программного кода.
Например, обычная операция импорта файла в каталоге, находящемся где-то в пути поиска модулей, выглядит так: тарогс псы!стев предлагая намного меньше информации, чем операция импорта, включающая путь к модулю: сарогс басвоаве.с!!еш .ос!!!стев я русооп »> Ггоа б1г1.б1г2 1арогС воб бсг1 !пст бтг2 сп1С сп аоб.ру »> аоб, г 3 »> Ггоа б1г1.б1г2.аоб 1арогт г »> г 3 »> 1арогс б1г1.б1г2.аоб ав аоб »> аоб.г 3 В Описание пути находится только в этои песте 528 Глава 20.
Пакеты модулей Операция импортирования пакетов может также упростить задание переменной окружения РУТНОНРАТН и файлов.рзй, хранящих настройки пути поиска модулей. Фактически, если вы используете импортирование пакетов для всех имеющихся каталогов, где хранится ваш программный код, и импорт производится относительно общего корневого каталога, вам достаточно будет добавить единственную запись в путь поиска модулей: общий корневой каталог.
Наконец, операция импортирования пакетов способна разрешать неоднозначности за счет явного и точного указания импортируемых файлов. В следующем разделе эта роль исследуется более подробно. История о трех программах Единственный случай, когда операция импортирования действительно необходима, — зто разрешение неоднозначностей, которые могут возникать, когда на одной машине установлено множество программ, содержащих файлы с одинаковыми именами. В определенной степени зто проблема установки программ, но она может стать источником беспокойств в обычной практике. Давайте рассмотрим гипотетическую ситуацию, чтобы проиллюстрировать эту проблему. Предположим, что программист разработал программу на языке Ру11топ, которая содержит файл именем иЫШез.ру, хранящий вспомогательный программный код, и файл та1п.ру, используемый для запуска программы.