Упаковка Python для относительного импорта
Прежде всего: извините, я знаю, что было много вопросов об относительном импорте, но я просто не нашел решения. Если возможно, я хотел бы использовать следующую структуру каталогов:
myClass/
__init__.py
test/
demo.py
benchmark.py
specs.py
src/
__init__.py
myClass.py
Теперь мои вопросы:
Как тестовые файлы из пакета правильно импортируют myClass.py?
Как бы вы импортировали пакет извне, предполагая, что вы используете myClass как подмодуль в libs / myClass или include / myClass?
До сих пор я не мог найти элегантное решение для этого. Из того, что я понимаю Решение Гвидо, должно быть возможно сделать from ..src import myClass
но это будет ошибка:
ValueError: Attempted relative import in non-package
Который выглядит так, как будто он не рассматривает myClass как пакеты. Чтение документов:
Файлы __init__.py необходимы для того, чтобы Python рассматривал каталоги как содержащие пакеты;
Кажется, мне не хватает чего-то, что указывает, где находятся скрипты пакета, я должен использовать.pth?
3 ответа
ValueError: Attempted relative import in non-package
Означает, что вы пытаетесь использовать относительный импорт в модуле, который не является пакетом. Его проблема с файлом, который имеет это from ... import
заявление, а не файл, который вы пытаетесь импортировать.
Так, например, если вы выполняете относительный импорт в своих тестах, вы должны сделать свои тесты частью своего пакета. Это означает
- Добавление
__init__.py
тестировать/ - Запуск их из какого-то внешнего сценария, как тесты носа
Если вы запускаете что-то как python myClass/test/demo.py
Относительный импорт не будет работать, так как вы используете демонстрационный модуль не как пакет. Относительный импорт требует, чтобы модуль, который их использует, импортировался сам как модуль пакета, from myClass.test.demo import blabla
или с относительным импортом.
После нескольких часов поисков прошлой ночью я нашел ответ относительно относительного импорта в python! Или, по крайней мере, простое решение. Лучший способ исправить это - вызвать модули из другого модуля. Так сказать хочешь demo.py
импортировать myClass.py
, в myClass
папка в корне подпакетов, они должны иметь файл, который вызывает два других. Из того что я собираю рабочий каталог всегда считается __main__
так что если вы проверяете импорт из demo.py
с demo.py
сценарий, вы получите эту ошибку. Проиллюстрировать:
Иерархия папок:
myClass/
main.py #arbitrary name, can be anything
test/
__init__.py
demo.py
src/
__init__.py
myClass.py
myClass.py:
def randomMaths(x):
a = x * 2
y = x * a
return y
demo.py:
from ..src import myClass
def printer():
print(myClass.randomMaths(42))
main.py:
import test.demo
demo.printer()
Если вы бежите demo.py
в интерпретаторе вы выдадите ошибку, но работаете main.py
не буду. Это немного запутанно, но это работает:D
Внутри-пакет-ссылки описывает, как myClass
от test/*
, Чтобы импортировать пакет извне, вы должны добавить его путь к PYTHONPATH
переменная среды перед запуском приложения-импортера или sys.path
список в коде, прежде чем импортировать его.
Зачем from ..src import myClass
не удается: возможно, src
это не пакет Python, вы не можете импортировать оттуда. Вы должны добавить его в путь Python, как описано выше.