Лутц М. - Изучаем Python (1077325), страница 109
Текст из файла (страница 109)
Проще говоря, модули — это всего лишь пространства имен (места, где создаются имена), и имена, находящиеся в модуле, называются его атрибутами. В этом разделе мы исследуем, как работает этот механизм. Файлы создают пространства имен Итак, как же файлы трансформируются в пространства имен? Суть в том, что каждое имя, которому присваивается некоторое значение на верхнем уровне файла модуля (то есть не вложенное в функции или в классы), превращается в атрибут этого модуля.
Например, операция присваивания, такая как Х = 1, на верхнем уровне модуля М.ру, превращает имя Х в атрибут модуля И, обратиться к которому нз-за пределов модуля можно как И. Х. Кроме того, имя Х становится глобальной переменной для программного кода внутри М.ру, но нам необходимо более формально объяснить понятия загрузки модуля и областей видимости, чтобы понять почему: ° Инструкции модуля выполняются во время первой попытки импорта. Когда модуль импортируется в первый раз, интерпретатор РуФЬоп создает пустой объект модуля и выполняет инструкции в модуле одну за другой, от начала файла до конца.
° Операции присваивания, выполняемые на верхнем уровне, создают атрибуты модуля. Во время импортирования инструкции присваивания выполняемые на верхнем уровне файла и не вложенные в инструкции 6ег или с1азв (например, =, 6е1) создают атрибуты объекта модуля — при присваивании имена сохраняются в пространстве имен модуля. ° Доступ к пространствам имен модулей можно получить через атрибуты 6(ст или 6(г(И). Пространства имен модулей, создаваемые операцией импортирования, представляют собой словари — доступ к ним можно получить через встроенный атрибут 6тст, ассоциированный с модулем, и с помощью функции от г.
Функция бт г — это примерный эквивалент отсортированного списка ключей атрибута отсс, но она включает унаследованные имена классов, может возвращать не полный список и часто изменяется от версии к версии. ° Модуль — это единая область видимости (локальная является глобальной). Как мы видели в главе 16, имена на верхнем уровне модуля подчиняются тем же правилам обращения/присваивания, что имена в функциях, только в этом случае локальная область видимо- 510 Глаза 19.
Основы программирования модулей сти совпадает с глобальной (точнее, они следуют тому же правилу А ЕСВ поиска в областях видимости, с которым мы познакомились в главе 16, только без уровней поиска Ь и Е). Но в модулях область еидимости модуля после загрузки модуля превращается в атрибут- словарь объекта модуля. В отличие от функций (где локальное пространство имен существует только во время выполнения функции), область видимости файла модуля превращается в область видимости атрибутов объекта модуля и никуда не исчезает после выполнения операции импортирования. Ниже эти понятия демонстрируются в программном коде.
Предположим, что мы создаем в текстовом редакторе следующий файл модуля с именем то<(и1е2.рр: ргет 'егаг11пд го 1оаб.. >воог1 зуе паве = 42 бег голо(): разе с1аее к1аез: разе рг>пс боле 1оаб1пд.' Когда модуль будет импортироваться в первый раз (или будет запущен как программа), интерпретатор выполнит инструкции модуля от начала до конца. В ходе операции импортирования одни инструкции создают имена в пространстве имен модуля, а другие выполняют определенную работу. Например, две инструкции рг101 в этом файле выполняются во время импортирования: »> 1врогт вобо1е2 егег<1пд со 1оаб... попе 1оаб1пд. Но как только модуль будет загружен, его область видимости превратится в пространство имен атрибутов объекта модуля, который возвращает инструкция евро гс.
После этого можно обращаться к атрибутам в этом пространстве имен, дополняя их именем вмещающего модуля: »> вобо1е2.еуе <зоб о1е ' еуе ' (от11-1п ) > »> вобо1е2, паве 42 »> вобо1е2,топо <Гопо11оп Гопс а1 Ох012В1030> »> вобо1е2. К1еее <С1аээ Всбо1Е2. К1аеэ аг ОК011СОВАО> Здесь именам зуз, паве, Гопс и К1азз были присвоены значения во время выполнения инструкций модуля, поэтому они стали атрибутами после завершения операции импортирования. О классах мы будем говорить Пространства имен модулей в шестой части книги, но обратите внимание на атрибут ауа — инструкции (арогт действительно присваивают объекты модулей именам, а любая операция присваивания на верхнем уровне файла создает атрибут модуля.
Внутри интерпретатора пространства имен хранятся в виде объектов словарей. Это самые обычные объекты словарей с обычными методами. Обратиться к словарю пространства имен модуля можно через атрибут о1ст модуля: »> аозс1е2. О1сс . Кеуа() [' 11!о ', 'паве'. ' пане ', 'ауа', ' сос ', ' ьс1!ттпа К)ааа', ттспс'1 Имена, которые были определены в файле модуля, становятся ключами внутреннего словаря, таким образом, большинство имен здесь отражают операции присваивания на верхнем уровне в файле.
Однако интерпретатор Ру()топ добавляет в пространство имен модуля еще несколько имен, например 1 1е содержит имя файла из которого был загружен модуль, а паве — это имя под которым модуль известен импортерам (без расширения .ру и без пути к каталогу). Дополнение имен атрибутов После ознакомления с модулями мы должны поближе рассмотреть понятие дополнения имен. В языке Ру()топ для доступа к атрибутам любого объекта используется синтаксис дополнения имени оо) ес1, а11г(Ос1е. Дополнение имени — зто в действительности выражение, возвращающее значение, присвоенное имени атрибута, ассоциированного с объектом. Например, выражение аобс1е2, ауа в предыдущем примере возвращает значение атрибута ауа в объекте аоао1е2.
Точно так же, если имеется встроенный объект списка с, выражение с. аррепо вернет метод арраса, ассоциированный с этим списком. Итак, какую роль играет дополнение имен атрибутов с точки зрения правил, рассмотренных нами в главе 16? В действительности — никакую: это совершенно независимые понятия. Когда вы обращаетесь к именам, используя дополнение, вы явно указываете интерпретатору объект, атрибут которого требуется получить. Правило ЬЕОВ применяется только к кратким, неполным именам. Ниже приводятся принятые правила: Простые переменные Использование краткой формы имени, например Х, означает, что будет произведен поиск этого имени в текущих областях видимости (следуя правилу 1 ЕОВ). Полные имена Имя Х.
У означает, что будет произведен поиск имени Х в текущих областях видимости, а затем будет выполнен поиск атрибута у в объекте Х (не в областях видимости). 51г Глава 19, Основы программирования модулей Полные мути Имя Х. у. 7 означает, что будет произведен поиск имени У в объекте Х, а затем поиск имени 7 в объекте Х. У. Общий сл уч ай Дополнение имен применимо ко всем объектам, имеющим атрибуты: модулям, классам, расширениям типов на языке С и т. д.
В шестой части книги мы увидим, что дополнение имен для классов имеет немного большее значение (здесь также имеет место то, что на- зывается маследовамиелг), но в общем случае правила, описанные здесь, применяются ко всем именам в языке РуФ)1оп.
Импортирование и области видимости й Переиенная Х. глобальная тол~ко для этого файла Х = 88 оег гп; 9)ова) Х Х = 99 В Изменяет переменную Х в этои файле В Ииена в других иодулях недоступна Второй модуль, тот(Ь ру, определяет свою собственную глобальную пе- ременную Х, а также импортирует и вызывает функцию из первого мо- дуля: а переменная Х.' глобальная тол~ко для этого файла Х = 11 (ирогг иова В Получает доступ к именам в иодупе попа исоа.г() а Иэиенлет переменную юоеа.х, но не Х в этои файле ргтпг Х, юооа.Х При запуске этого модуля функция арба.
Г изменит переменную Х в мо- дуле зоба, а не в вовс. Глобальной областью видимости для функции зо- ба. Г всегда является файл, вмещающий ее, независимо от того, из ка- кого модуля она была вызвана: % руспоп юобв.ру 11 99 Другими словами, операция импортирования никогда не изменяет область видимости для программного кода в импортируемом файле — из Как мы уже знаем, невозможно получить доступ к именам, определенным в другом модуле, не импортировав его предварительно, То есть вы никогда автоматически не получите доступ к именам в другом файле, независимо от вида импортируемого модуля и вызовов функций в вашей программе. Смысл переменной всегда определяется местоположением операции присваивания в программном коде, а для обращения к атрибутам всегда необходимо явно указывать объект. Например, рассмотрим два следующих простых модуля.
Первый, то. с(ачру, определяет переменную Х, которая является глобальной только для программного кода в этом файле, и функцию, изменяющую глобальную переменную Х в этом файле: Пространства имен модулей 513 импортируемого файла нельзя получить доступ к именам в импортирующем файле. Если быть более точным: ° Функциям никогда не будут доступны имена, определенные в других функциях, если только они физически не вложены друг в друга. ° Программному коду модуля никогда не будут доступны имена, определенные в других модулях, если только они явно не были импортированы. Вложенные пространства имен Операция импорта не дает возможности доступа к внешним областям видимости, но она дает возможность обращаться к вложенным областям видимости.
Используя полные пути к именам атрибутов, вполне возможно погрузиться в сколь угодно глубоко вложенные модули и получить доступ к их атрибутам. Например, рассмотрим следующие три файла. Файл тодЗгру определяет единственное глобальное имя и атрибут операцией присваивания: Х=З Файл тодйчоу определяет свою переменную Х, затем импортирует мо- дуль вобЗ и использует дополнение имени, чтобы получить доступ к ат- рибуту импортированного модуля: Х=2 тврогт воЗЗ Л Моя глобальная переменная Х Л Глобальная переиенная К из модуля впбз ргпк Х, ргзпт всоЗ.Х Файл тоь23ру также определяет свою собственную переменную Х, за- тем импортирует модуль воб2 и получает значения атрибутов обоих мо- дулей: Х= 1 тврогт всб2 ртпт Х, Л Мпя глобальная переиеннзя Х рмпт вос2.х, л переиеннея к из модуля воб2 рг1пт воб2.восз.х и переменная х из ипдупя вобз Некоторые языки программирования подразумевают иной порядок действий н реализуют динамические области видимости, когда области видимости з действительности могут зависеть от вызовов функций во время выполнения программы.