Я знаю, что есть много подобных или одинаковых вопросов, но я все еще не могу понять / найти правильный способ для меня работать с модулями. Python - мой любимый язык, и мне нравится все в нем, кроме работы с импортом: рекурсивный импорт (когда вы пытаетесь сослаться на имя, которого еще нет), пути импорта и т. Д.
Итак, у меня есть такая структура проекта:
my_project/
package1/
__init__.py
module1
module2
package2/
__init__.py
module1
module2
Package1
может использоваться автономное устройство, но также ожидается, что оно будет импортировано package2
.
Что я делаю сейчас, это то, что, например, в package1.module1
я пишу from package1 import module2
, то есть используя полный путь к импортированному модулю. Я делаю это потому, что если я использую import module2
- это не будет работать, когда модуль будет импортирован из другого пакета (package2
). Я также не могу использовать from . import module2
- это не будет работать при непосредственном запуске module1
.
ОК, поэтому для from package1 import module2
в package1.module1
для работы в обоих случаях (при прямом запуске package1.module1
и при импорте из package2
) я добавляю эти строки в начале package1.module1
:
import os, sys
currDir = os.path.dirname(os.path.realpath(__file__))
rootDir = os.path.abspath(os.path.join(currDir, '..'))
if rootDir not in sys.path: # add parent dir to paths
sys.path.append(rootDir)
Для меня это работает, но я чувствую, что это не питон. Я делаю что-то не так?
Должен ли я вместо этого всегда запускать package1.module1
из корня проекта? Если это так, это делает его неудобным для запуска из IDE - мне нужно как-то установить пути в нем.
ОБНОВЛЕНИЕ: Я пытался добавить файл root.pth
в package1
dir с содержанием ..
. Но это не сработало - я думаю, оно предназначено для чего-то другого.
Выводы:
Всегда используйте абсолютный импорт: import package1.module1
Добавьте загрузчик в корневую папку, чтобы запустить некоторые модули в виде отдельного скрипта. Это решает запуск скрипта из среды IDE и является питоническим подходом.
22.04.07 Бретт Кэннон написал:
Этот PEP изменяет идиому if __name__ == "__main__": ...
на
if __name__ == sys.main: ...
чтобы у тебя был хотя бы шанс
выполнить модуль в пакете, использующем относительный импорт.
Пробежал этот PEP мимо идей питона. Остановил обсуждение там, когда тоже
было предложено много новых идей. =) Я перечислил их всех в
раздел «Отклоненные идеи», хотя подавляющая поддержка одной
выходит вперед, ПКП может перейти к одному из них.
Я -1 на этом и на любом другом предложенном тидлинге __main__
техника. Кажется, что единственный вариант использования - запуск сценариев
жить в каталоге модуля, который я всегда видел как
антипаттерн. Чтобы заставить меня передумать, ты должен убедить меня, что
это не так.
- Гвидо ван Россум