Я решил поместить код модуля непосредственно в пакеты __init__.py
, даже для простых пакетов, где этот файл оказывается единственным файлом.
Итак, у меня есть несколько пакетов, которые выглядят так (хотя они не все называются pants
:)
+ pants/
\-- __init__.py
\-- setup.py
\-- README.txt
\--+ test/
\-- __init__.py
Я начал делать это, потому что это позволяет мне поместить код в отдельный (и, что критически, отдельно версии) каталог, и заставить его работатьтак же, как если бы пакет находился в одном module.py
.Я храню их в моей директории dev python lib, которую я добавил в $PYTHONPATH
при работе с такими вещами.Каждый пакет представляет собой отдельный репозиторий git.
edit ...
По сравнению с типичным макетом пакета Python, как показано в Radomir ' answer , эта установка избавляет меня от необходимости добавлять каталог каждого пакета в мою PYTHONPATH.
... / edit
Это сработало довольно хорошо, но я столкнулся с этим (нескольконепонятно) проблема:
При запуске тестов из каталога пакета сам пакет, т. е. код в __init__.py
, не обязательно находится на sys.path
.Это не проблема в моей типичной среде, но если кто-то скачает pants-4.6.tgz
и извлечет архив с исходным кодом cd
s в каталог и запустит python setup.py test
, сам пакет pants
не будет нормальнобыть в их sys.path
.
Я нахожу это странным, потому что я ожидал бы, что setuptools
будет запускать тесты из родительского каталога тестируемого пакета.Однако, по какой-то причине, он этого не делает, я думаю, потому что обычно вы бы не упаковывали вещи таким образом.
Относительный импорт не работает, потому что test
- это пакет верхнего уровня, имеющийбыл найден как подкаталог компонента current-directory sys.path
.
. Я бы хотел избежать перемещения кода в отдельный файл и импорта его открытых имен в __init__.py
.Главным образом потому, что это кажется бессмысленным беспорядком для простого модуля.
Я мог бы явно добавить родительский каталог в sys.path
из setup.py
, но предпочел бы этого не делать.С одной стороны, это может, по крайней мере, теоретически, потерпеть неудачу, например, если кто-то решит запустить тест из корня своей файловой системы (предположительно, с диска Windows).Но в основном это просто фальшивка.
Есть ли лучший способ?
Считается ли особенно плохой формой вставлять код в __init__.py
?