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

Импорт Python из родительского каталога

У меня есть следующее:

         ModuleFolder
              |
              |-->. ModuleFile.py .
              |
              '-->. TestsFolder .
                         |
                         '---> UnitTest1.py

Я пытаюсь импортировать из родительского каталога. В этом случае я пытаюсь запустить "UnitTest1.py" из тестовой папки и импортировать из каталога непосредственно над ним (файл "ModuleFile.py" ).

  • Я знаю, что на это уже много ответов. SO Question1, SO Question2, Каждый другой вопрос SO. Я просто не мог найти "использование../" как относительный импорт, а не явный путь.
  • Я знаю, что с Python 2.5 они поддерживали "относительный импорт" в соответствии с документацией, в которой упоминается использование from .. import *, но я специально пытаюсь сделать import MyModuleName, поэтому я могу быть более явным в unittest и избегать mangling/collisions of names.

То, что я делаю (и это работает для меня), следующее:

sys.path.append("../")

И затем импортируйте то, что мне нужно из родительского каталога.

  • Да, в родительском каталоге есть __init__.py,
  • Нет, мой родительский путь не является частью пути Python или переменной среды
  • Почему бы мне просто не добавить родительский путь к sys.path? Потому что это относительный. Если я бегу из /home/workspace/MyModule/unittests/, а мой модуль находится в/home/workspace/MyModule/Я предположил, что добавление/home/workspace/MyModule/в путь не обязательно будет истинным, если сотрудник выполнит это на его машине под своим собственным каталогом /home/documents/MyModule.

Мой вопрос:

Правильно ли это Python? Если нет, то что с этим не так. Есть ли способ лучше? Или это действительно RTFM-момент, когда ответ находится в одном из вопросов 7+ SO, на которые я уже смотрел? (Я видел тех, кто рекомендовал явный путь, а не подход относительного пути, который я взял).

Другая полезная информация:

  • Python 2.6
  • Работа в Linux, но так же легко перепрыгнуть на Win.
4b9b3361

Ответ 1

Не запускайте тест из папки тестов. Запустите его из корня вашего проекта, который является папкой модуля. Вам очень редко приходится гадать с помощью sys.path или PYTHONPATH, а когда вы это делаете, вы либо вызываете ошибки для других библиотек в дороге, либо делаете жизнь более трудной для ваших пользователей.

python -m TestsFolder.UnitTest1

Если вы используете тестовый бегун, например py.test, вы можете просто запустить py.test из корня вашей проверки и найти тесты для вас, (Предполагая, что вы называете свои тесты чем-то более похожими на test_unit1.py. Ваша текущая схема именования немного неортодоксальная.;))

Ответ 2

Лучше вставить свой относительный путь при начале sys.path следующим образом:

import sys
sys.path.insert(0, '../')

Ответ 3

Мое предложение:

Не пытайтесь быть умными, делайте то, что вы должны делать. То есть убедитесь, что ваши модули и пакеты находятся где-то на вашем пути Python.

Самый простой способ - установить переменную среды PYTHONPATH в оболочке, которую вы используете для выполнения своих скриптов:

$ export PYTHONPATH=/the/directory/where/your/modules/and/packages/are
$ cd /the/directory/where/your/unit/tests/are
$ python test1.py

Ответ 4

Сделайте тестовую папку модулем (добавив __ init __. py).
Затем вы можете использовать run python -m tests.test_name или использовать следующий Makefile в своем проекте дома:

TEST_FILES = $(wildcard tests/test_*.py)
TESTS = $(subst .py,,$(subst /,.,$(TEST_FILES)))
all.PHONY: test
test:
    @- $(foreach TEST,$(TESTS), \
        echo === Running test: $(TEST); \
        python -m $(TEST); \
        )

Ответ 5

Вы также можете сделать символическую ссылку на путь модуля, который хотите импортировать, а затем использовать символическую ссылку для импорта. Создайте символическую ссылку в dist-пакетах python.

Чтобы создать символическую ссылку:

ln -s "/path/to/ModuleFolder" "/path/to/python/dist/packages/module_symlink_name"

Чтобы импортировать модуль в script:

from module_symlink_name import ModuleFile

Не нужно экспортировать путь python или модифицировать путь sys.