- Часть I. Вводное руководство
- Глава 2. Использование интерпретатора
- 2.2. Интерпретатор и его среда
- 6.6. Пакеты
6.6. Пакеты
Пакеты — способ структурирования пространств имён модулей, используя "точечную запись". Например, имя модуля A.B обозначает подмодуль с именем A в пакете B. Так же, как использование модулей делает безопасным использование глобального пространства имён авторами различных модулей, использование точечной записи делает безопасным использование имён модулей авторами многомодульных пакетов.
Предположим, Вы хотите спроектировать совокупность модулей ("пакет") для единообразной обработки звуковых файлов и данных. Существует множество форматов звуковых файлов (обычно распознаваемых по их расширению, например '.wav', '.flac', '.mp3'), так что Вам необходимо создавать и поддерживать всё возрастающий набор модулей для преобразования между различными форматами файлов. Вы можете захотеть выполнять множество различных операций над звуковыми данными (микширование, добавление эха, частотная обработка, создание искусственного стереоэффекта), то есть, вдобавок, Вы будете писать нескончаемый поток модулей для выполнения этих операций. Вот примерная структура Вашего пакета (выраженная в терминах иерархической файловой системы):
Sound/ Верхний уровень пакета
__init__.py Инициализация пакета
Formats/ Работа с файлами
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
Effects/ Звуковые эффекты
__init__.py
echo.py
surround.py
reverse.py
...
Filters/ Фильтры
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
Файл '__init__.py' необходим для того, чтобы Python распознавал каталог, как содержащий пакет — таким образом предотвращается маскировка полноценных модулей, расположенных далее в путях поиска, каталогами с распространёнными именами (такими как 'string'). В простейшем случае, '__init__.py' — пустой файл, но может содержать код инициализации пакета и/или устанавливать переменную __all__, описанную ниже.
Пользователи пакета могут импортировать индивидуальные модули пакета, например:
import Sound.Effects.echo
В этом случае загружается модуль Sound.Effects.echo. На него нужно ссылаться по полному имени:
Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)
Вы можете использовать альтернативный способ импортирования подмодуля:
from Sound.Effects import echo
В этом случае также загружается модуль Sound.Effects.echo, и делает его доступным для использования без префикса:
echo.echofilter(input, output, delay=0.7, atten=4)
Ещё один вариант — импортировать желаемую функцию или переменную непосредственно:
from Sound.Effects.echo import echofilter
И в этом случае загружается модуль Sound.Effects.echo, но на этот раз, функция echofilter() становится доступной для использования непосредственно:
echofilter(input, output, delay=0.7, atten=4)
Заметим, что при использовании 'from package import item', item может быть модулем, подпакетом или другим именем, определенном в пакете package, таким как функция, класс или переменная. Инструкция import сначала проверяет, определёно ли имя item в пакете, если нет, считает его модулем и пытается загрузить. Если при загрузке возникает ошибка, генерируется исключение ImportError.
И наоборот, при использовании инструкции 'import item.subitem.subsubitem', каждая единица, кроме последней, должна быть пакетом. Последняя единица может быть модулем или пакетом, но не может быть классом, функцией или переменной, определённой в предыдущей единице.