Ответ 1
TL;DR:
- Запустите ваш код с помощью
python -m pkg.mod2
. - Импортируйте свой код с помощью
from. import mod1
from. import mod1
.
Единственное "решение", которое я нашел, - это зайти в одну папку и
python -m pkg.mod2
и тогда оноpython -m pkg.mod2
.
Использование переключателя -m
действительно является "единственным" решением - раньше оно уже было единственным. Старое поведение просто всегда срабатывало из чистой удачи; это может быть сломано даже без изменения вашего кода.
Переход "на одну папку вверх" просто добавляет ваш пакет в путь поиска. Установка вашего пакета или изменение пути поиска также работает. Смотрите ниже для деталей.
Но нужно ли добавлять префикс пакета pkg к каждому импорту в другие модули в этом пакете?
У вас должна быть ссылка на ваш пакет - в противном случае не ясно, какой модуль вы хотите. Ссылка на пакет может быть абсолютной или относительной.
Относительный импорт, как правило, то, что вы хотите. Это позволяет сэкономить на написании pkg
, что упрощает рефакторинг и перемещение модулей.
# inside mod1.py
# import mod2 - this is wrong! It can pull in an arbitrary mod2 module
# these are correct, they uniquely identify the module
import pkg.mod2
from pkg import mod2
from . import mod2
from .mod2 import foo # if pkg.mod2.foo exists
Обратите внимание, что вы всегда можете использовать <import> as <name>
чтобы связать ваш импорт с другим именем. Например, import pkg.mod2 as mod2
позволяет работать только с именем модуля.
Более того, чтобы запустить какие-либо скрипты внутри пакета, нужно ли помнить, чтобы перейти на одну папку вверх и использовать переключатель -m? Это единственный путь?
Если ваш пакет установлен правильно, вы можете использовать переключатель -m
из любого места. Например, вы всегда можете использовать python3 -m json.tool
.
echo '{"json":"obj"}' | python -m json.tool
Если ваш пакет не установлен (пока), вы можете установить PYTHONPATH
в его базовый каталог. Это включает ваш пакет в путь поиска и позволяет переключателю -m
найти его правильно.
Если вы находитесь в каталоге исполняемых файлов, вы можете выполнить export PYTHONPATH="$(pwd)/.."
чтобы быстро смонтировать пакет для импорта.
Я не совсем понимаю. Этот сценарий был довольно прост с Python 2, но выглядит неуклюжим в Python 3.
Этот сценарий был в основном нарушен в Python 2. Несмотря на то, что во многих случаях он был простым, его было трудно или просто невозможно исправить ни в каких других случаях.
Новое поведение является более неуклюжим в прямом случае, но надежным и надежным в любом случае.