Упаковка 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 заявление, а не файл, который вы пытаетесь импортировать.

Так, например, если вы выполняете относительный импорт в своих тестах, вы должны сделать свои тесты частью своего пакета. Это означает

  1. Добавление __init__.py тестировать/
  2. Запуск их из какого-то внешнего сценария, как тесты носа

Если вы запускаете что-то как 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, как описано выше.

Другие вопросы по тегам