Подтвердить что ты не робот

Упаковка питона для относительного импорта

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

myClass/
    __init__.py
    test/
        demo.py
        benchmark.py
        specs.py
    src/
        __init__.py
        myClass.py

Теперь мои вопросы:

  • Как тестовые файлы из пакета правильно импортируют myClass.py?

  • Как вы импортируете пакет извне, если вы примете myClass в качестве подмодуля в libs/myClass или include/myClass?

До сих пор я не мог найти изящного решения для этого. Из того, что я понимаю Guido Decision, можно сделать from ..src import myClass, но это будет ошибка:

ValueError: Attempted relative import in non-package

Что выглядит так, как не обрабатывать myClass как пакеты. Чтение документов:

Файлы __init__.py необходимы, чтобы Python рассматривал каталоги как содержащие пакеты;

Кажется, мне не хватает чего-то, что указывает, где скрипты пакета, следует ли использовать .pth?

4b9b3361

Ответ 1

ValueError: Attempted relative import in non-package

означает, что вы пытаетесь использовать относительный импорт в модуле, который не является пакетом. Его проблема с файлом, который имеет этот оператор from ... import, а не файл, который вы пытаетесь импортировать.

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

  • Добавление __init__.py для проверки /
  • Запуск их из некоторого внешнего script, например, nosetests

Если вы запускаете что-то как python myClass/test/demo.py, относительный импорт не будет работать, так как вы используете демонстрационный модуль не как пакет. Относительный импорт требует, чтобы модуль, который их использует, сам импортируется либо как модуль пакета, from myClass.test.demo import blabla, либо с относительным импортом.

Ответ 2

После нескольких часов поиска прошлой ночью я нашел ответ на относительный импорт в python!! Или простое решение, по крайней мере. Лучший способ исправить это, чтобы модули вызывались из другого модуля. Скажем, вы хотите, чтобы demo.py импортировал myClass.py в папке MyClass в корневой части подпакетов игрушка должна иметь файл, который вызывает два других. Из того, что я собираю, рабочий каталог всегда считается основным, поэтому, если вы протестируете импорт из demo.py с помощью demo.py script, вы получите эту ошибку. Чтобы проиллюстрировать:

папка hierarcy:

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

Ответ 3

Intra-package-references описывает, как myClass от test/*. Чтобы импортировать пакет извне, вы должны добавить свой путь к переменной среды PYTHONPATH перед запуском приложения-импортера или в список sys.path в коде перед импортом.

Почему from ..src import myClass не удается: возможно, src не является пакетом python, вы не можете импортировать его. Вы должны добавить его в путь python, как описано выше.