Марк Лутц - Изучаем Python, Четвертое издание (1184811), страница 26
Текст из файла (страница 26)
Содержимое модуля становится доступным внешнему миру через его атрибуты (определение этого термина я дамв следующем разделе).Такая модульная модель является центральной идеей, лежащей в основе архитектуры программ на языке Python. Крупные программы обычно организованы в виде множества файлов модулей, которые импортируют и используютфункциональные возможности из других модулей. Один из модулей определяется как основной файл верхнего уровня, который запускает всю программу.Проблемы модульной архитектуры мы будем рассматривать подробнее позже, в этой же книге, а в этой главе основное внимание уделяется тому факту,что операция импорта на заключительном этапе приводит к выполнению программного кода загружаемого файла. Как следствие, импорт файла являетсяеще одним способом запустить его.Например, если запустить интерактивный сеанс работы с интерпретатором(в IDLE, из командной строки или как-то иначе), можно будет запустить файлscript1.py, созданный ранее, с помощью простой инструкции import (не забудьте перед этим удалить инструкцию input, добавленную в предыдущем разделе,иначе вам придется нажимать клавишу Enter без всякой необходимости):C:\misc> c:\python30\python>>> import script1win321267650600228229401496703205376Spam!Spam!Spam!Spam!Spam!Spam!Spam!Spam!Такой способ пригоден только для однократного запуска модуля в течение сеанса.
После первой операции импорта все последующие попытки импортировать модуль не приводят ни к каким результатам, даже если изменить и сохранить исходный текст модуля в другом окне:>>> import script1>>> import script1Так сделано преднамеренно – операция импорта требует слишком больших затрат вычислительных ресурсов, чтобы выполнять ее более одного раза в ходевыполнения программы. Как вы узнаете в главе 21, в ходе импорта производится поиск файлов, компиляция их в байт-код и выполнение этого байт-кода.Если действительно возникает необходимость вынудить интерпретатор многократно запускать файл в рамках одного и того же сеанса (без остановкии перезапуска сеанса), можно воспользоваться встроенной функцией reload,доступной в модуле imp из стандартной библиотеки (в ��������������������Python�������������� 2.6 эта функция была обычной встроенной функцией, но в Python 3.0 она была перенесенав модуль imp):>>> from imp import reload # В версии 3.0 требуется загрузить функцию>>> reload(script1)win3265536Spam!Spam!Spam!Spam!Spam!Spam!Spam!Spam!<module ‘script1’ from ‘script1.py’>>>>96Глава 3.
Как пользователь запускает программыИнструкция from в этом примере просто копирует имя функции из модуля (подробнее об рассказывается ниже). Функция reload загружает и запускает текущую версию программного кода в файле, если он был изменен в другом окне.Это позволяет редактировать и использовать новый программный код в ходеодного и того же интерактивного сеанса работы с интерпретатором Python.В этом сеансе, например, уже после того как модуль был импортирован, втораяинструкция print в файле script1.py была изменена в другом окне так, чтобыона выводила результат выражения 2 ** 16, после чего была выполнена перезагрузка модуля с помощью функции reload.Функция reload ожидает получить имя уже загруженного модуля, поэтому,прежде чем перезагрузка станет возможной, модуль должен быть импортирован.
Примечательно также, что имя модуля при вызове функции reload должно быть заключено в круглые скобки, тогда как инструкция import не требуетэтого. Дело в том, что reload – это функция, которая вызывается, а import – этоинструкция.Именно поэтому имя модуля следует передавать функции reload как аргумент,в круглых скобках и именно поэтому после перезагрузки модуля выводится дополнительная строка.
Последняя строка в выводе выше – это всего лишь представление результата, возвращаемого функцией reload после перезагрузки модуля. Более подробно функции будут обсуждаться в главе 16.Примечание, касающееся различий между версиями: в версииPython 3.0 встроенная функция reload была перемещена в модуль imp из стандартной библиотеки. Она точно так же перезагружает файлы, как и прежде, но перед использованием ее необходимо импортировать. В версии 3.0 можно использовать инструкцию import imp и затем вызывать функцию как imp.reload(M),или использовать инструкцию from imp import reload и вызыватьфункцию как reload(M), как показано в примере выше.
Инструкции import и from рассматриваются в следующем разделе, а болееформально они описываются далее в книге.Если вы используете версию Python 2.6 (или другую версию изветки 2.X), функция reload доступна как встроенная функция,которую не нужно импортировать.
В Python 2.6 функция reloadдоступна в двух видах – как встроенная функция и как функция в модуле imp, чтобы упростить переход на версию 3.0. Другими словами, возможность перезагрузки модулей сохраниласьв версии 3.0, но чтобы воспользоваться ею, функцию reload необходимо импортировать.Перемещение функции в версии 3.0, вероятно, отчасти было вызвано известными проблемами, связанными с инструкциями reload и from, с которыми мы познакомимся в следующем разделе.В двух словах, имена, загруженные с помощью инструкции from,не обновляются вызовом функции reload, а имена, загруженныеинструкцией import, – обновляются. Если вы обнаружите, чтокакие-то импортированные компоненты не обновляются послевызова функции reload, попробуйте использовать инструкциюimport и обращаться к компоненту в формате module.attribute.Импортирование и перезагрузка модулей97Важные сведения о модулях: атрибутыОперации импортирования и перезагрузки модулей обеспечивают естественный способ запуска программы, так как на заключительном этапе этих операций производится исполнение файлов.
При этом в более широком пониманиимодули играют роль библиотек инструментов, как вы узнаете в пятой частикниги. Модуль – это, главным образом, всего лишь пакет имен переменных,известный как пространство имен. Имена внутри этого пакета называютсяатрибутами, то есть атрибут – это имя переменной, которая связана с определенным объектом (таким как модуль).В самом типичном случае импортирующий программный код получает доступко всем именам верхнего уровня, определяемым в файле модуля. Эти именаобычно связаны с функциональными возможностями, экспортируемыми модулем – функциями, классами, переменными и так далее, которые предназначены для использования в других файлах и программах.
Снаружи доступк именам в файле модуля можно получить с помощью двух инструкций языкаPython, import и from, а также с помощью вызова функции reload.Для иллюстрации вышесказанного создайте с помощью текстового редактораоднострочный файл модуля Python с именем myfile.py со следующим содержимым:title = “The Meaning of Life”Это, пожалуй, один из самых простых модулей Python (он содержит единственную операцию присваивания), но его вполне достаточно для иллюстрации основных положений. При импортировании этого модуля выполняется егопрограммный код, который создает атрибут модуля.
Инструкция присваивания создает атрибут с именем title.Доступ к атрибуту title можно получить из других программных компонентовдвумя разными способами. Первый заключается в том, чтобы загрузить модуль целиком с помощью инструкции import, а затем обратиться к атрибуту поего имени, уточнив его именем модуля:% python# Запуск интерпретатора Python>>> import myfile# Запуск файла; модуль загружается целиком>>> print(myfile.title) # Имя атрибута, уточненное именем модуля через ‘.’The Meaning of LifeВообще синтаксис точечной нотации в виде object.attribute позволяет получитьдоступ к любому атрибуту в любом объекте, и этот прием широко используетсяв программном коде на языке Python. Здесь мы использовали его для обращения к строковой переменной title, определенной внутри модуля myfile – то естьmyfile.title.Кроме того, доступ к именам внутри модулей (Фактически создать копии имен)можно получать с помощью инструкции from:% python# Запуск интерпретатора Python>>> from myfile import title # Запуск файла; выполняется копирование имен>>> print(title) # Имя атрибута используется напрямую, уточнение не требуетсяThe Meaning of Life98Глава 3.
Как пользователь запускает программыКак будет говориться позднее, инструкция from во многом подобна инструкцииimport, которая выполняет присваивание имен в импортируемом компоненте.С технической точки зрения, инструкция from копирует атрибуты модулятак, что они становятся простыми переменными в программном коде, выполняющем импорт, благодаря чему на этот раз он может обратиться к импортированной строке уже не по имени myfile.title (ссылка на атрибут), а просто –title (переменная).1Неважно, как выполняется импортирование модуля, с помощью инструкцииimport или from, в любом случае это приводит к выполнению инструкций в файле myfile.py, а импортирующий компонент (в данном случае – интерактивнаяоболочка интерпретатора) получает доступ к именам, определенным в файле на верхнем уровне.
В этом простом примере существует только одно такоеимя – переменная title, которой присвоена строка, но сама концепция приобретает более важное значение, когда речь заходит об определении в модуляхтаких объектов, как функции и классы. Такие объекты становятся программными компонентами многократного использования, доступ к которым можнополучить из одного или более клиентских модулей.На практике модули обычно определяют более чем одно имя, которые могутиспользоваться и внутри, и за пределами модуля. Ниже приводится примермодуля, в котором определяются три имени:a = ‘dead’# Определяются три атрибута,b = ‘parrot’ # экспортируемые другим модулямc = ‘sketch’print a, b, c # Кроме того, они используются и самим этим модулемВ файле threenames.py создаются три переменные, которые становятся тремяатрибутами, доступными внешнему миру.