Главная страница
Навигация по странице:

  • ...вернитесь обратно в интерактивную оболочку...

  • Закрепление пройденного Контрольные вопросы

  • Основы операции импортирования пакетов

  • Пакеты и настройка пути поиска

  • Пример импортирования пакета

  • Математический анализ. 3е издание


    Скачать 4.86 Mb.
    Название3е издание
    АнкорМатематический анализ
    Дата04.02.2022
    Размер4.86 Mb.
    Формат файлаpdf
    Имя файлаpython_01.pdf
    ТипДокументы
    #351981
    страница63 из 98
    1   ...   59   60   61   62   63   64   65   66   ...   98
    518
    Глава 19. Основы программирования модулей
    Не закрывая интерактивную оболочку интерпретатора, отредактируй
    те файл модуля в другом окне:
    ...измените файл changer.py, не останавливая интерактивный сеанс...
    % vi changer.py
    Измените глобальную переменную message, а также тело функции printer
    :
    message = "After editing"
    def printer():
    print 'reloaded:', message
    Затем вернитесь в окно интерактивной оболочки и перезагрузите мо
    дуль, чтобы выполнить обновленный программный код. Обратите вни
    мание: в следующем листинге видно, что операция импортирования модуля не дает желаемого результата – на экран выводится первона
    чальный текст сообщения, несмотря на то что файл был изменен. Что
    бы задействовать новую версию, необходимо вызвать функцию reload:
    ...вернитесь обратно в интерактивную оболочку...
    >>> import changer
    >>> changer.printer() # Никакого эффекта: используется прежняя версия модуля
    First version
    >>> reload(changer) # Принудительная загрузка/выполнение нового кода

    >>> changer.printer() # Теперь будет запущена новая версия
    reloaded: After editing
    Обратите внимание, что функция reload в действительности возвраща
    ет объект – обычно ее результат игнорируется, но поскольку интерак
    тивная оболочка автоматически выводит результат выражения, ин
    терпретатор вывел результат в виде строки .
    В заключение
    В этой главе были рассмотрены основные инструменты, используемые при программировании модулей, – инструкции import и from, и функ
    ция reload. Мы узнали, что инструкция from просто выполняет один дополнительный шаг, на котором она копирует имена из файла после того, как он будет импортирован, и что функция reload принудительно выполняет операцию импортирования файла без остановки и переза
    пуска интерпретатора Python. Мы также рассмотрели понятия про
    странства имен, увидели, что происходит при вложенных операциях импортирования, узнали, как файлы становятся пространствами имен модулей, и познакомились с некоторыми потенциальными ло
    вушками инструкции from.
    Мы уже достаточно знаем, чтобы начать работать с файлами модулей в наших программах, и тем не менее в следующей главе приводятся расширенные сведения о модели импортирования – об импортирова

    Закрепление пройденного
    519
    нии пакетов – о способе, с помощью которого инструкции import мож
    но указать относительный путь к каталогу, где находится требуемый модуль. Как мы увидим, возможность импортирования пакетов обес
    печивает механизм, удобный для крупных систем и позволяющий из
    бежать конфликтов между одинаковыми именами модулей. Но преж
    де чем двинуться дальше, постарайтесь ответить на контрольные во
    просы по представленным здесь идеям.
    Закрепление пройденного
    Контрольные вопросы
    1. Как создать модуль?
    2. Как взаимосвязаны инструкции from и import?
    3. Какое отношение к операции импортирования имеет функция re
    load
    ?
    4. Когда вместо инструкции from следует использовать инструкцию import
    ?
    5. Назовите три потенциальных ловушки инструкции from.
    6. Какова скорость полета ласточки без груза?
    Ответы
    1. Чтобы создать модуль, достаточно просто создать текстовый файл с инструкциями на языке Python; любой файл с исходным про
    граммным кодом автоматически становится модулем – нет ника
    ких синтаксических конструкций для его объявления. Можно так
    же создать модуль, написав программный код на другом языке про
    граммирования, таком как C или Java, но такие модули находятся вне рассмотрения этой книги.
    2. Инструкция from импортирует модуль целиком, как и инструкция import
    , но кроме этого она еще копирует одно или более имен из им
    портируемого модуля в ту область видимости, где находится инст
    рукция from. Это позволяет использовать импортированные имена напрямую (name), без дополнения их именем модуля (module.name).
    3. По умолчанию модуль импортируется один раз за все время выпол
    нения программы. Функция reload принудительно выполняет по
    вторное импортирование. Она часто используется, чтобы загрузить новую версию исходного программного кода модуля в процессе раз
    работки и в случаях динамической настройки.
    4. Инструкция import обязательно должна использоваться вместо ин
    струкции from, только когда необходимо обеспечить доступ к одно
    му и тому же имени в двух разных модулях – поскольку вы будете вынуждены указывать имена вмещающих модулей, эти два имени будут уникальны.

    520
    Глава 19. Основы программирования модулей
    5. Инструкция from может делать непонятным смысл переменной (в ка
    ком модуле она определена), вызывать проблемы при использова
    нии функции reload (имена могут ссылаться на прежние версии объектов) и может повреждать пространства имен (может приво
    дить к перезаписи значений имен, используемых в вашей области видимости). Самой худшей, во многих отношениях, является фор
    ма from * – она может приводить к серьезным повреждениям про
    странств имен и скрывать смысл переменных – эту форму инструк
    ции следует использовать с большой осторожностью.
    6. А какая ласточка имеется в виду? Африканская или европейская?

    20
    Пакеты модулей
    До сих пор, импортируя модули, мы загружали файлы. Это типичный способ использования модулей, и скорее всего, этот прием будет вами использоваться наиболее часто в начале вашей карьеры программиста на языке Python. Однако возможности импортирования модулей не
    много богаче, чем я предлагал вам считать до настоящего момента.
    Помимо возможности импортировать имя модуля существует возмож
    ность импортировать имена каталогов. Каталог, как говорят на языке
    Python, является пакетом, поэтому такая операция импортирования называется импортированием пакетов. В действительности, опера
    ция импортирования пакета превращает имя каталога в еще одну раз
    новидность пространства имен, в котором атрибутам соответствуют подкаталоги и файлы модулей, находящиеся в этих каталогах.
    Это немного усложненная особенность, но иерархическая структура,
    которую она создает, оказывается удобной для организации файлов в крупных системах и в большинстве случаев упрощает настройку пу
    ти поиска модулей. Как мы увидим дальше, операция импортирова
    ния пакетов иногда оказывается просто необходимой, чтобы избежать неоднозначности при наличии нескольких файлов программ с одина
    ковыми именами, установленных на одном компьютере.
    Основы операции импортирования пакетов
    Так как же работает импортирование пакетов? В инструкциях import,
    там, где вы указывали имя простого файла, можно указать список имен в пути к каталогу, разделяя их символами точки:
    import dir1.dir2.mod
    То же самое относится и к инструкции from:
    from dir1.dir2.mod import x

    522
    Глава 20. Пакеты модулей
    Предполагается, что такой «точечный» путь в этих инструкциях соот
    ветствует пути через иерархию каталогов на вашей машине, ведущему к файлу mod.py (или к файлу с похожим именем – расширение в имени файла может быть другим). Таким образом, предыдущие инструкции указывают, что на вашей машине имеется каталог dir1, в котором су
    ществует подкаталог dir2, в котором находится файл модуля mod.py
    (или с похожим именем).
    Кроме того, эти инструкции предполагают, что каталог dir1 находится внутри некоторого контейнерного каталога dir0, который находится в пути поиска модулей. Другими словами, обе инструкции импорта предполагают наличие структуры каталогов, которая выглядит при
    мерно так, как показано ниже (здесь в качестве разделителей имен ка
    талогов используется символ обратного слеша, принятый в операци
    онной системе DOS):
    dir0\dir1\dir2\mod.py # Или mod.pyc, mod.so и т. д.
    Контейнерный каталог dir0 должен быть добавлен в путь поиска моду
    лей (если это не домашний каталог главного файла программы), как если бы имя dir1 было именем модуля. Инструкция import в вашем сценарии определяет пути, ведущие непосредственно к модулям, на
    чиная от этого каталога.
    Пакеты и настройка пути поиска
    Если вы используете эту возможность, имейте в виду, что пути к ката
    логам в инструкции import могут содержать только имена переменных,
    разделенные точками. Здесь нельзя использовать синтаксис путей к ка
    талогам, специфичный для текущей платформы, как, например,
    C:\dir1
    , My Documents.dir2 или ../dir1 – это недопустимый синтаксис.
    Вместо этого платформозависимый синтаксис используйте в настрой
    ках путей поиска модулей, именуя необходимые каталогиконтейнеры.
    Так, в предыдущем примере dir0 – это имя каталога, которое требует
    ся добавить в путь поиска модулей и которое может иметь произволь
    ную длину и путь, с учетом специфики используемой платформы, ве
    дущий к каталогу dir1. Вместо того чтобы использовать ошибочный синтаксис, как показано ниже:
    import C:\mycode\dir1\dir2\mod # Ошибка: недопустимый синтаксис
    добавьте путь C:\mycode в переменную окружения PYTHONPATH или в файл
    .pth
    (предполагается, что это не домашний каталог программы, по
    скольку в этом случае этот шаг не является необходимым) и исполь
    зуйте такую инструкцию: import dir1.dir2.mod
    В сущности, записи в списке путей поиска модулей содержат платфор
    мозависимые пути к каталогам, которые ведут к самым левым именам

    Основы операции импортирования пакетов
    523
    в цепочках, представленных в инструкциях import, а сами инструкции import предоставляют окончание пути к каталогам платформонезави
    симым способом.
    1
    Файлы пакетов _ _init_ _.py
    Если вы решили использовать импортирование пакетов, существует еще одно условие, которое необходимо будет соблюдать: каждый ката
    лог в пути, указанном в инструкции импортирования пакета, должен содержать файл с именем _ _init_ _.py, в противном случае операция импорта пакета будет терпеть неудачу. То есть в примере выше катало
    ги dir1 и dir2 должны содержать файл с именем _ _init_ _.py; каталог
    контейнер dir0 может не содержать такой файл, потому что сам он не указан в инструкции импортирования пакета. Точнее говоря, для та
    кой структуры каталогов:
    dir0\dir1\dir2\mod.py и инструкции импортирования, имеющей следующий вид:
    import dir1.dir2.mod применяются следующие правила:

    dir1
    и dir2 должны содержать файл _ _init_ _.py.

    dir0
    , каталогконтейнер, может не содержать файл _ _init_ _.py
    этот файл будет проигнорирован, если он присутствует.

    dir0
    , но не dir0\dir1, должен присутствовать в пути поиска модулей
    (то есть он должен быть домашним каталогом или присутствовать в переменной окружения PYTHONPATH и т. д.).
    Таким образом, структура каталогов в этом примере должна иметь следующий вид (здесь отступы указывают на вложенность каталогов):
    dir0\ # Каталогконтейнер в пути поиска модулей
    dir1\
    __init__.py dir2\
    __init__.py mod.py
    1
    Символ точки как разделитель имен каталогов был выбран не только для обеспечения независимости от используемой платформы, но и потому, что пути в инструкциях import в действительности становятся вложенными объектами пути. Этот синтаксис также подразумевает, что вы будете полу
    чать невразумительные сообщения об ошибках, если забудете опустить расширение .py. Например, инструкция import mod.py подразумевает, что выполняется импорт пути к каталогу, – она загрузит mod.py, затем попыта
    ется загрузить mod\py.py, что в конечном счете приведет к появлению сби
    вающего с толку сообщения об ошибке.

    524
    Глава 20. Пакеты модулей
    Файлы _ _init_ _.py могут содержать программный код на языке Py
    thon, как любые другие файлы модулей. Отчасти они являются объяв
    лениями для интерпретатора и могут вообще ничего не содержать. Эти файлы, будучи объявлениями, предотвращают неумышленное сокры
    тие в каталогах с совпадающими именами истинно требуемых моду
    лей, если они отображаются позже в списке путей поиска модулей. Без этого защитного механизма интерпретатор мог бы выбирать каталоги,
    которые не имеют никакого отношения к вашему программному коду,
    только лишь потому, что в пути поиска они появляются ранее.
    В общем случае файл _ _init_ _.py предназначен для выполнения дей
    ствий по инициализации пакета, создания пространства имен для ка
    талога и реализации поведения инструкций from * (то есть from ... im
    port *
    ), когда они используются для импортирования каталогов:
    Инициализация пакета
    Когда интерпретатор Python импортирует каталог в первый раз, он автоматически запускает программный код файла _ _init_ _.py это
    го каталога. По этой причине обычно в эти файлы помещается про
    граммный код, выполняющий действия по инициализации, необ
    ходимые для файлов в пакете. Например, этот файл инициализа
    ции в пакете может использоваться для создания файлов с данны
    ми, открытия соединения с базой данных и т. д. Обычно файлы
    _ _init_ _.py
    не предназначены для непосредственного выполнения –
    они запускаются автоматически, когда выполняется первое обра
    щение к пакету.
    Инициализация пространства имен модуля
    При импортировании пакетов пути к каталогам в вашем сценарии после завершения операции импортирования превращаются в на
    стоящие иерархии вложенных объектов. Например, в предыдущем примере после завершения операции импортирования можно будет использовать выражение dir1.dir2, которое возвращает объект мо
    дуля, чье пространство имен содержит все имена, определяемые файлом _ _init_ _.py из каталога dir2. Такие файлы создают про
    странства имен для объектов модулей, соответствующих катало
    гам, в которых отсутствуют настоящие файлы модулей.
    Поведение инструкции from *
    В качестве дополнительной особенности, в файлах _ _init_ _.py мож
    но использовать списки __all__, чтобы определить, что будет им
    портироваться из каталога инструкцией from *. (Мы познакомимся со списком __all__ в главе 21.) Список __all__ в файлах _ _init_ _.py
    представляет собой список имен субмодулей, которые должны им
    портироваться, когда в инструкции from * указывается имя пакета
    (каталога). Если список __all__ отсутствует, инструкция from * не будет автоматически загружать субмодули, вложенные в каталог, –
    она загрузит только имена, определяемые инструкциями присваи
    вания в файле _ _init_ _.py, включая любые субмодули, явно импор

    Пример импортирования пакета
    525
    тируемые программным кодом в этом файле. Например, инструк
    ция from submodule import X в файле _ _init_ _.py создаст имя X в про
    странстве имен каталога.
    Эти файлы можно оставить пустыми, если вам не требуется выполнять специальных действий. Однако для успешного выполнения операции импортирования каталогов они должны существовать обязательно.
    Пример импортирования пакета
    Рассмотрим практический пример программного кода, который де
    монстрирует, как используются файлы инициализации и пути к ката
    логам. Следующие три файла располагаются в каталоге dir1 и в подка
    талоге dir2:
    # Файл: dir1\__init__.py print 'dir1 init'
    x = 1
    # Файл: dir1\dir2\__init__.py print 'dir2 init'
    y = 2
    # Файл: dir1\dir2\mod.py print 'in mod.py'
    z = 3
    В данном случае каталог dir1 может быть подкаталогом нашего рабо
    чего каталога (то есть домашнего каталога программы) или подкатало
    гом одного из каталогов, перечисленных в пути поиска модулей (с точ
    ки зрения реализации: каталога, входящего в список sys.path). В лю
    бом из этих случаев для каталога, вмещающего подкаталог dir1, не требуется наличие файла _ _init_ _.py.
    Инструкции import выполняют файл инициализации в каждом ката
    логе, который присутствует в пути к модулю, – инструкции print, при
    сутствующие в этих файлах, позволят отследить их выполнение. Кро
    ме того, как и файлы модулей, уже импортированные каталоги могут передаваться функции reload для принудительного повторного испол
    нения этого единственного элемента. Как показано ниже, для повтор
    ной загрузки каталогов и файлов функция reload также может прини
    мать цепочку имен, разделенных точками:
    % python
    >>> import dir1.dir2.mod # Сначала запускаются файлы инициализации
    dir1 init dir2 init in mod.py
    >>>
    >>> import dir1.dir2.mod # Повторное импортирование не выполняется
    >>>
    >>> reload(dir1)

    526
    Глава 20. Пакеты модулей dir1 init

    >>>
    >>> reload(dir1.dir2)
    dir2 init

    После операции импортирования путь, указанный в инструкции im
    port
    , становится цепочкой вложенных объектов. Здесь mod – это объ
    ект, вложенный в объект dir2, который в свою очередь вложен в объ
    ект dir1:
    >>> dir1

    >>> dir1.dir2

    >>> dir1.dir2.mod

    Каждый каталог в пути фактически становится переменной, которой присваивается объект модуля, пространство имен которого инициали
    зируется всеми инструкциями присваивания в файле _ _init_ _.py, на
    ходящемся в этом каталоге. Имя dir1.x ссылается на переменную x,
    которой присваивается значение в файле dir1\_ _init_ _.py, точно так же, как имя mod.z ссылается на переменную z, которой присваивается значение в файле mod.py:
    >>> dir1.x
    1
    >>> dir1.dir2.y
    2
    >>> dir1.dir2.mod.z
    3
    Инструкции from и import для пакетов
    Использование инструкции import может оказаться несколько неудоб
    ным для импортирования пакетов, потому что в этом случае далее в про
    грамме вам придется часто вводить полные пути для обращения к име
    нам. В примере из предыдущего раздела, например, приходилось каж
    дый раз вводить полный путь от dir1, когда необходимо было обратить
    ся к переменной z. Если попытаться непосредственно обратиться к dir2
    или mod, будет получено сообщение об ошибке:
    >>>
    1   ...   59   60   61   62   63   64   65   66   ...   98


    написать администратору сайта