Импорт 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.
Ответы
Ответ 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.