Namespace пакеты в Python

Содержание
Введение
Поиск Namespace пакетов
Executable Directories
Executable Zip Files
Executable Packages
Похожие статьи

Введение

Перед изучением этой статьи убедитесь, что вам знакома тема sys.path в Python

PEP 420

Namespace пакеты это механизм, с помощью которого один Python пакет разбивается по различным директориям на диске.

Так как директорий в корых находится namespace пакет несколько, не существует какого-то единого __init__.py файла. Поэтому __init__.py файла вообще может не быть.

При импорте namespace пакета никакой код не будет выполнен по умолчанию.

Поиск Namespace пакетов

Рассмотрим структуру обычного пакета из статьи Пакеты в Python

demo_reader ├── compressed │ ├── bzipped.py │ ├── gzipped.py │ └── __init__.py ├── __init__.py ├── multireader.py └── util ├── __init__.py └── writer.py

Раскидаем этот пакет по двум директориям

project ├── path1 │ └── demo_reader │ ├── multireader.py │ └── util │ ├── __init__.py │ └── writer.py └── path2 └── demo_reader └── compressed ├── bzipped.py ├── gzipped.py └── __init__.py

>>> import sys >>> sys.path.extend(['./path1', './path2']) >>> import demo_reader >>> demo_reader.__path__

_NamespacePath(['/home/andrei/python/./path1/demo_reader', '/home/andrei/python/./path2/demo_reader'])

>>> import demo_reader.util >>> import demo_reader.compressed >>> demo_reader.util.__path__

['/home/andrei/python/./path1/demo_reader/util']

>>> demo_reader.compressed.__path__

['/home/andrei/python/./path2/demo_reader/compressed']

Проверить, что всё работает как и до разбиения на части можно выполнив те же самые команды

>>> import sys >>> sys.path.extend(['./path1', './path2']) >>> from demo_reader.multireader import MultiReader >>> r = MultiReader('test.bz2') >>> r.read() 'data compressed with bz2'

Executable Directories

Рассмотрим проект из этого урока

python ├── multi-reader-program │ └── demo_reader │ ├── compressed │ │ ├── bzipped.py │ │ ├── gzipped.py │ │ └── __init__.py │ ├── __init__.py │ ├── multireader.py │ └── util │ ├── __init__.py │ └── writer.py ├── test.bz2 └── test.gz

Попытка выполнить директорию приведёт к ошибке

python multi-reader-program

/home/andrei/.pyenv/versions/3.9.5/bin/python: can't find '__main__' module in '/home/andrei/python/multi-reader-program'

Добавим в корень директории multi-reader-program файл __main__.py

# multi-reader-program/__main__.py print('executing multi-reader-program/__main__.py')

python multi-reader-program

executing multi-reader-program/__main__.py

Когда Python выполняет файл __main__.py он добавляет директорию в которой находится этот файл в sys.path затем из __main__.py можно импортировать любой скрипт из этой директории.

Изменим код __main__.py

# multi-reader-program/__main__.py import sys from demo_reader.multireader import MultiReader filename = sys.argv[1] r = MultiReader(filename) print(r.read()) r.close()

Теперь можно выполнить директорию

python multi-reader-program ./test.bz2

demo reader is being imported data compressed with bz2

Executable Zip Files

Рассмотрим код из предыдущего параграфа

python ├── multi-reader-program │ ├── demo_reader │ │ ├── compressed │ │ │ ├── bzipped.py │ │ │ ├── gzipped.py │ │ │ └── __init__.py │ │ ├── __init__.py │ │ ├── multireader.py │ │ └── util │ │ ├── __init__.py │ │ └── writer.py │ └── __main__.py ├── test.bz2 └── test.gz

cd multi-reader-program
python -m zipfile -c ../multi-reader-program.zip *
cd ..
ls

multi-reader-program multi-reader-program.zip test.bz2 test.gz

python multi-reader-program.zip test.gz

demo reader is being imported data compressed with gz by Andrei

Executable Package

Рассмотрим код из предыдущего параграфа, но директорию demo_reader вынесем из директории multi-reader-program

Добавим в директорию demo_reader файл __main__.py

ch4-executable-package ├── demo_reader │ ├── compressed │ │ ├── bzipped.py │ │ ├── gzipped.py │ │ └── __init__.py │ ├── __init__.py │ ├── __main__.py │ ├── multireader.py │ └── util │ ├── __init__.py │ └── writer.py ├── test.bz2 └── test.gz

python demo_reader test.gz

Traceback (most recent call last): File "/home/andrei/.pyenv/versions/3.9.5/lib/python3.9/runpy.py", line 197, in _run_module_as_main return _run_code(code, main_globals, None, File "/home/andrei/.pyenv/versions/3.9.5/lib/python3.9/runpy.py", line 87, in _run_code exec(code, run_globals) File "/home/andrei/python/demo_reader/__main__.py", line 7, in <module> from demo_reader.multireader import MultiReader ModuleNotFoundError: No module named 'demo_reader'

Выполнение директорий и пакетов отличается

python directory python -m directory
Выполняется директория Выполняется пакет

Опция -m указывает Python обращаться с directory как с модулем
directory добавляется в sys.path directory обрабатывается как пакет
directory/__main__.py не содержится в пакете directory/__main__.py это подмодуль пакета directory

В текущем примере, нужно обрабатывать demo_reader как модуль

python -m demo_reader test.gz

demo reader is being imported data compressed with gz

Похожие статьи
Пакеты в Python
Namespace пакеты в Python
Правильная структура пакета
setuptools
Плагины
Python

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящую по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: