Пути импорта - правильный путь?

Я знаю, что есть МНОГО похожих или одинаковых вопросов, но я все еще не могу понять / найти правильный способ работы с модулями. Python - мой любимый язык, и мне нравится все в нем, кроме работы с импортом: рекурсивный импорт (когда вы пытаетесь сослаться на имя, которого еще нет), пути импорта и т. Д.

Итак, у меня есть такая структура проекта:

my_project/
    package1/
        __init__.py
        module1
        module2
    package2/
        __init__.py
        module1
        module2

Package1 может использоваться как автономный модуль, но также ожидается, что он будет импортирован с помощью package2 . Что я сейчас делаю, так это то, что, например, в package1.module1 я пишу из package1 import module2 , то есть использую полный путь к импортированному модулю. Я делаю это, потому что если я использую import module2 -это не сработает, если модуль будет импортирован из другого пакета ( package2 ). Я также не могу использовать из. import module2 - это не будет работать при прямом запуске module1 .

ОК, поэтому для из 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 ] каталог с содержимым .. . Но это не сработало - я предполагаю, что это предназначено для чего-то другого.

ВЫВОДЫ:

  1. Всегда используйте абсолютный импорт: import package1.module1

  2. Добавьте загрузчик в корневую папку, чтобы запустить некоторые из модули как отдельный скрипт. Это решает задачу запуска сценария в среде IDE и представляет собой питонический подход.

22 апреля 2007 г. Бретт Кэннон написал:

Этот PEP предназначен для изменения if __name__ == "__main__": .. . идиома если __name__ == sys.main: ... чтобы у тебя был хотя бы шанс для выполнения модуля в пакете, который использует относительный импорт.

Прогнал этот PEP мимо идей Python. Прекратил обсуждение там, когда тоже Предлагалось много новых идей. =) Я перечислил их все в раздел "Отклоненные идеи", хотя подавляющая поддержка одной выходит вперед, PEP может перейти к одному из них.

Я -1 на этом и на любых других предлагаемых твидлингах __ main __ машины. Единственный вариант использования, кажется, запускает скрипты, которые происходят жить в каталоге модуля, который я всегда считал антипаттерн. Чтобы заставить меня изменить свое мнение, вам нужно убедить меня, что это не так.

- Гвидо ван Россум

27
задан warvariuc 15 September 2014 в 17:34
поделиться