2013-12-26 2 views
1

Когда вы пишете библиотеку python и хотите импортировать в нее один модуль из другого, что это правильный способ сделать это, чтобы импорт работал как при импорте библиотеки извне, так и при выполнении некоторых модульных тестов из библиотечный каталог?Каков правильный способ импорта модулей в библиотеку python?

Если вы

import some_module 
from some_module import something 

он работает при запуске из библиотеки directoy, но при ввозе из-за пределов, производит ImportError: No module named 'some_module'.

Вы можете сделать

from . import some_module 
import my_library.some_other_module 
from .some_module import something 

, но это не будет работать, если вы импортировать библиотеку из UnitTest помещенной в том же каталоге.

И, наконец, вы можете играть с sys.path и/или переместить модульные тесты в другой каталог.

Какое оптимальное решение?

Редактировать: Просто, чтобы было ясно, я хотел бы запустить unittests, используя python -m unittest в верхней папке библиотеки. До сих пор я сделал это, добавив

import os 
import sys 
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 

в начало тестовых файлов устройства. В качестве альтернативы можно написать короткий сценарий оболочки, который добавит родительский каталог в PYTHONPATH, а затем запустит unittests. Интересно, есть ли лучшие способы справиться с этим?

+0

Воспроизведение с помощью 'PYTHONPATH' вместо' sys.path' возможно ... –

ответ

0

Взгляните на Документов на Module Search Path

Когда модуль с именем спам импортируется, интерпретатор сначала ищет для встроенного модуля с этим именем. Если он не найден, он ищет для файла с именем spam.py в списке каталогов, заданных переменной переменной sys.path . sys.path инициализируется из этих мест:

  • каталог, содержащий входной скрипт (или текущий каталог).
  • PYTHONPATH (список имен каталогов, с тем же синтаксисом, что и переменная оболочки PATH).
  • зависит от установки по умолчанию.

Если вы пишете библиотеку, тестовый код должен обычно интерфейс с библиотекой таким же образом, что пользователь библиотеки будет. Это может означать добавление модуля в путь поиска либо путем установки переменной окружения PYTHONPATH, либо путем установки модуля в местоположении модуля по умолчанию.

Я хотел бы предложить продолжить тесты из базового каталога, который хранит ваши модули с использованием автоматизированной опции обнаружения теста

python -m unittest discover (python >= 2.7) 

Это будет рекурсивно найти файлы, соответствующие test_*.py (т.е. в пределах модуля директорий), но следует установить питон путь относительно родительского каталога.

+0

Выполнение unittests из родительского каталога не похоже на хорошее решение, поскольку оно сканирует все несвязанные подкаталоги в родительском каталоге. –

+0

Python ищет те же самые каталоги при импорте модуля, поэтому, если у вас есть избыточные файлы в пути поиска python, возможно, реструктуризация в порядке. На практике поиск почти мгновен для большинства проектов. Вы также можете запускать определенные модули из родительского каталога, например, 'python -m foo.tests.test_bar' –

Смежные вопросы