Настройка подмодулей Python3 не обновляет пути при запуске с ключом -m

У меня есть следующая структура проекта:

server/ server.py __init__.py sockets/ module.py __init__.py 

Я устанавливаю PYTHONPATH в один каталог выше сервера (например, /home/user/server содержит сервер, PYTHONPATH установлен /home/user ).

Основной файл – server.py ; он импортирует модули:

 import sockets from sockets.module import Module 

Когда я запускаю python3 $PYTHONPATH/server/server.py он работает отлично. Однако, когда я вызываю python3 -m server.server.py он терпит неудачу, несмотря на то, что явно рекомендуется избегать python3 -m server.server.py Python, но он не находит модуль с уродливым сообщением:

 /usr/bin/python3: Error while finding spec for 'server.server.py' (<class 'ImportError'>: No module named 'sockets') 

Почему импорт модуля невозможен для импорта подмодулей? Как правильно настроить подпакеты?

Поведение совершенно верно; sockets не являются модулем верхнего уровня . Однако, когда вы используете $PYTHONPATH/server/server.py , Python также добавляет $PYTHONPATH/server/ в путь поиска Python, поэтому теперь sockets являются модулем верхнего уровня. Вы никогда не должны напрямую запускать файлы в пакете.

Импорт sockets относительно текущего пакета:

 from . import sockets from .sockets.module import Module 

или использовать полностью квалифицированный импорт:

 from server import sockets from server.sockets.module import Module 

Также см. Раздел « Параметры интерфейса» раздела «Настройка и использование Python» в тонком руководстве:

Если имя сценария относится непосредственно к файлу Python, каталог, содержащий этот файл, добавляется в начало sys.path , и файл выполняется как модуль __main__ .

Обратите внимание, что ключ -m принимает идентификатор python , а не имя файла, поэтому используйте:

 python -m server.server 

оставляя расширение .py .