Книга: Как устроен Python. Гид для разработчиков, программистов и интересующихся
Назад: 24. Импортирование библиотек
Дальше: 26. Полноценный пример

25. Библиотеки: пакеты и модули

В главе 24 вы научились импортировать библиотеки. В этой главе мы разберемся в том, что же представляет собой библиотека. При импортировании библиотеки действуют два требования:

1. Библиотека должна представлять собой модуль или пакет.

2. Библиотека должна находиться в месте, определяемом переменной среды PYTHONPATH или переменной Python sys.path.

25.1. Модули

Модули представляют собой файлы Python с расширением .py и именем, пригодным для импортирования. Согласно PEP 8, имена файлов модулей должны быть короткими и записываться в нижнем регистре. Символы подчеркивания могут использоваться для удобства чтения.

25.2. Пакеты

Пакет в Python представляет собой каталог, содержащий файл с именем __init__.py. Файл __init__.py может содержать любую реализацию (или вообще быть пустым). Кроме того, каталог может содержать произвольное количество модулей и субпакетов.

Что лучше использовать при написании кода — модуль или пакет? Я обычно начинаю с более простого варианта и использую модуль. А если мне нужно выделять отдельные части в собственные модули, я преобразую модули в пакет.

Пример структуры каталога из популярного проекта SQLAlchemy (средство объектно-реляционного отображения для баз данных):

sqlalchemy/

__init__.py

engine/

__init__.py

base.py

schema.py

Согласно PEP 8, имена каталогов пакетов должны быть короткими и записываться в нижнем регистре. Символы подчеркивания в них недопустимы.

25.3. Импортирование пакетов

Чтобы импортировать пакет, используйте команду import с именем пакета (именем каталога):

>>> import sqlalchemy

Эта команда импортирует файл sqlalchemy/__init__.py в текущее пространство имен, если пакет будет найден в PYTHONPATH или sys.path.

Если вы захотите использовать классы Column и ForeignKey из модуля schema.py, подойдет любой из следующих фрагментов. Первый включает sqlalchemy.schema в ваше пространство имен, а второй помещает в пространство имен только schema:

>>> import sqlalchemy.schema

>>> col = sqlalchemy.schema.Column()

>>> fk = sqlalchemy.schema.ForeignKey()

или

>>> from sqlalchemy import schema

>>> col = schema.Column()

>>> fk = schema.ForeignKey()

А если вам нужен только класс Column, импортируйте этот класс одним из двух способов:

>>> import sqlalchemy.schema.Column

>>> col = sqlalchemy.schema.Column()

или

>>> from sqlalchemy.schema import Column

>>> col = Column()

25.4. PYTHONPATH

Переменная среды PYTHONPATH содержит список нестандартных каталогов, в которых Python ищет модули или пакеты. Обычно эта переменная пуста. Изменять PYTHONPATH обычно не обязательно, если только вы в процессе разработки не хотите использовать библиотеки, которые еще не были установлены.

СОВЕТ

Оставьте переменную PYTHONPATH пустой, если только у вас нет веских причин для ее изменения. В этом разделе показано, что может произойти при ее изменении. Последствия могут сбить с толку других разработчиков, пытающихся отладить ваш код, если они забудут о том, что переменная PYTHONPATH была изменена.

Если вы включили код в файл /home/test/a/plot.py, но работали из каталога /home/test/b/, использование PYTHONPATH предоставит доступ к этому коду. В противном случае, если файл plot.py не был установлен системными средствами или средствами Python, попытка его импортирования приведет к ошибке ImportError:

>>> import plot

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

ImportError: No module named plot

Если вы запустите Python с присваиванием значения переменной PYTHONPATH, она укажет Python, где нужно искать библиотеки:

$ PYTHONPATH=/home/test/a python3

Python 3.6.0 (default, Dec 24 2016, 08:01:42)

>>> import plot

>>> plot.histogram()

...

СОВЕТ

Для установки пакетов Python могут использоваться менеджеры пакетов, исполняемые файлы Windows или специализированные средства Python, такие как pip.

25.5. sys.path

У модуля sys имеется атрибут path со списком каталогов, в которых Python ищет библиотеки. Просмотрев sys.path, вы увидите все просмотренные каталоги:

>>> import sys

>>> sys.path

 

['',

'/usr/lib/python35.zip',

'/usr/lib/python3.6',

'/usr/lib/python3.6/plat-darwin',

'/usr/lib/python3.6/lib-dynload',

'/usr/local/lib/python3.6/site-packages']

СОВЕТ

Если вы сталкиваетесь с ошибкой вида

ImportError: No module named plot,

обратитесь к переменной sys.path и посмотрите, присутствует ли в ней каталог, в котором находится файл foo.py (если это модуль). Если plot является пакетом, то каталог plot/ должен находиться в одном из каталогов из sys.path:

>>> import plot

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

ImportError: No module named plot

>>> sys.path.append('/home/test/a')

>>> import plot

>>> plot.histogram()

Также можно включить этот каталог в PYTHONPATH из командной строки, используемой для запуска Python.

Еще раз подчеркнем, что обычно задавать вручную sys.path или PYTHONPATH не нужно. В нормальной ситуации вы устанавливаете библиотеки, а программа установки размещает их в правильном каталоге.

СОВЕТ

Если вы хотите узнать местонахождение библиотеки в файловой системе, проверьте атрибут __file__:

>>> import json

>>> json.__file__

'/usr/lib/python3.6/json/__init__.py'

Этот способ работает только с библиотеками, реализованными на Python. Модуль sys не реализован на Python, поэтому эта попытка завершается неудачей:

>>> import sys

>>> sys.__file__

Traceback (most recent call last):

...

AttributeError: module 'sys' has no attribute '__file__'

 

25.6. Итоги

В этой главе рассматриваются модули и пакеты. Модуль представляет собой файл Python. Пакет представляет собой каталог, в котором присутствует файл с именем __init__.py. Пакет также может содержать другие модули и пакеты.

Существует список путей, который определяет, к каким каталогам обращается Python для импортирования библиотек. Этот список хранится в sys.path. Проверив значение этой переменной, вы узнаете, какие каталоги просматривает Python. Вы также можете обновить этот список при помощи переменной PYTHONPATH или же внести изменения напрямую. Но обычно вместо изменения этой переменной вы используете специализированные средства установки пакетов, например pip.

25.7. Упражнения

1. Создайте модуль begin.py, который содержит функцию с именем prime. Функция prime должна получать число и возвращать логический признак того, является ли число простым (то есть делится ли оно только на 1 и на себя). Перейдите в другой каталог, запустите Python и выполните команду

from begin import prime

Попытка должна завершиться неудачей. Обновите переменную sys.path, чтобы вы могли импортировать функцию из модуля. Затем присвойте значение PYTHONPATH.

2. Создайте пакет utils. В файле __init__.py разместите код prime из предыдущего примера. Перейдите в другой каталог в терминале, запустите Python и выполните команду

from utils import prime

Попытка должна завершиться неудачей. Обновите переменную sys.path, чтобы вы могли импортировать функцию из пакета. Затем присвойте значение PYTHONPATH.

/

/

Назад: 24. Импортирование библиотек
Дальше: 26. Полноценный пример