Как выполнить кросс-импорт модулей в подкаталог, чтобы они работали как подмодуль и как отдельный модуль? - PullRequest
0 голосов
/ 28 июня 2019

У меня есть модуль Python, который обычно работает как автономный.

file1.py
file2.py
file3.py

Однако я также хочу, чтобы он был частью другого проекта, в котором модуль размещен в отдельном подкаталоге.

__init.py__
build.py
└── compiler
    └── __init__.py
    └── file1.py
    └── file2.py
    └── file3.py

Поскольку в скриптах модуля используется большое количество перекрестных импортов, это невозможно. Помещенные в подкаталог, импорт больше не находит соответствующие файлы, потому что он смотрит только в верхний каталог.

Чтобы решить проблему, я пробовал разные вещи. Я добавил подкаталог в качестве дополнительного пути в самом верхнем build.py скрипте.

sys.path.append('compiler')

Это не решило проблему. Перекрестный импорт все еще не работает.

Я также пробовал относительный импорт, но это нарушает автономную версию модуля. Итак, я попытался обработать исключения, чтобы поймать их

try:
    from file1 import TestClass
except ImportError:
    from .file1 import TestClass

Это тоже не сработало и привело, несмотря на все мои старания в ImportError: attempted relative import with no known parent package ошибках.

Я также пробовал всевозможные варианты этих вещей, но ничего из этого не сработало.

Я знаю, что должно быть возможно сделать что-то подобное, и я удивлен, что это так трудно сделать. Все мои поиски в Интернете вернулись с теми же предложениями - теми, что я изложил выше, но ни один из них не работал в моем случае, особенно потому, что они не учитывают возможность запуска кода в качестве отдельного модуля и субмодуля.

Я не могу быть первым, кто пытается написать модуль, который можно использовать как отдельный пакет или как субмодуль в других проектах. Что мне здесь не хватает?

1 Ответ

0 голосов
/ 28 июня 2019

Относительный импорт, как говорит ошибка, требует родительского пакета.Думайте о .file1 как сокращении для <this_module>.file1.Если нет <this_module>, вы не можете запросить file1.Чтобы правильно использовать относительный импорт, вам нужно будет создать проект-оболочку, которая будет содержать общий модуль, чтобы он мог быть должным образом распределен по именам.

Таким образом, ваш автономный модуль будет выглядеть следующим образом, в соответствии с потребителем:

__init.py__
standalone.py
└── compiler
    └── __init__.py
    └── file1.py
    └── file2.py
    └── file3.py

Другой вариант - сделать ваш общий модуль действительно устанавливаемым с помощью setup.py или pyproject.toml или любым другим вашим любимым методом.Затем вы устанавливаете его в потребляющем проекте вместо непосредственного его включения.

...