Я знаю, что есть много похожих или одинаковых вопросов, но я все еще не могу понять/найти правильный способ для работы с модулями. 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 - мне нужно как-то установить пути в нем.
UPDATE: я попытался добавить файл root.pth
в Package1
dir с содержимым ..
. Но это не сработало - я предполагаю, что это предназначено для чего-то еще.
Выводы:
-
Всегда используйте абсолютный импорт:
import package1.module1
-
Добавьте загрузчик в корневую папку, чтобы запустить некоторые из модулей в качестве автономного script. Это решает запустить script форму IDE и является питоническим подходом.
4/22/07, Бретт Кэннон написал:
Этот PEP должен изменить идиому
if __name__ == "__main__": ...
наif __name__ == sys.main: ...
, чтобы у вас был хотя бы шанс для выполнения модуля в пакете, который использует относительный импорт.Отправил этот PEP мимо идей python. Остановил обсуждение там, когда тоже было предложено много новых идей. =) Я перечислил все из них в раздел "Отклоненные идеи", хотя, если подавляющая поддержка одного приходит PEP может перейти на один из них.
Я нахожусь на этом и на любых других предлагаемых твидлингах __main__
техника. Единственный случай использования, похоже, работает с сценариями, которые происходят
чтобы жить внутри каталога модуля, который я всегда рассматривал как
антипаттерн. Чтобы заставить меня передумать, вы должны были бы убедить меня, что
это не так.