Настроить путь поиска модуля (PYTHONPATH) через pipenv
У меня есть проект Python, состоящий из ноутбука Jupyter, нескольких сценариев в каталоге bin
и модулей в каталоге src
с зависимостями в Pipfile
:
myproject
├── myproject.ipynb
├── Pipfile
├── Pipfile.lock
├── bin
│ ├── bar.py
│ └── foo.py
└── src
├── baz.py
└── qux.py
Скрипты foo.py
и bar.py
используют стандартный shebang
#!/usr/bin/env python
и может работать с pipenv shell
:
mymachine:myproject myname$ pipenv shell
(myproject-U308romt) bash-3.2$ bin/foo.py
foo
Однако я не могу легко получить доступ к модулям в src
из сценариев. Если я добавлю
import src.baz as baz
к foo.py
, я получаю:
ModuleNotFoundError: No module named 'src'
Одно из .env
- добавить файл .env
в myproject
:
PYTHONPATH=${PYTHONPATH}:${PWD}
Это работает благодаря pipenv
автоматической загрузки .env
, но проверка .env
файл в распределение мерзавца проекта будет сталкиваться с традиционным использованием .env
хранить секреты, такие как пароли - на самом деле, мое по умолчанию .gitignore
для Python проекты уже исключают .env
именно по этой причине.
$ git add .env
The following paths are ignored by one of your .gitignore files:
.env
Use -f if you really want to add them.
В качестве альтернативы, я мог бы перемещать src
под bin
, но тогда ноутбук Jupyter должен будет ссылаться на модули как bin.src.baz
и т.д., bin.src.baz
также является проблемой.
Мое текущее решение - просто добавить символическую ссылку:
myproject
├── Pipfile
├── Pipfile.lock
├── bin
│ ├── bar.py
│ ├── foo.py
│ └── src -> ../src
└── src
├── baz.py
└── qux.py
Это работает, и я полагаю, что имеет преимущество быть прозрачным, но кажется, что должен быть какой-то способ использовать pipenv
для решения одной и той же проблемы.
Есть ли переносимый, распространяемый способ поместить эти модули в путь поиска?
Ответы
Ответ 1
Я не уверен, что для этого есть идеальное решение, но в интересах быть явным, а не подразумеваемым (PEP 20), я решил проверить файл, который должен быть отправлен до запуска любого скрипта. Это один дополнительный ручной шаг, но вы можете поместить его в Makefile, например.
env.sh
export PYTHONPATH=${PYTHONPATH}:${PWD}
Makefile
bar:
source env.sh && pipenv run python scripts/bar.py
.PHONY: migrate
Решение немного похоже на подход Go принимает с его GOPATH
.
Я думаю, что другие решения не так хороши:
-
pipenv
направлен на решение зависимостей, я мог ошибаться, но я не нашел ничего, связанного с проблемой PYTHONPATH
. - Связывание папок не будет очень хорошо масштабироваться, если вы начнете использовать другую папку сценариев.
Ответ 2
(Пришел сюда за ответом, в итоге дал один вместо)
У меня похожая структура папок проекта, поэтому у меня была такая же проблема.
Благодаря вашему .env
добавить файл .env
на том же уровне, что и Pipfile
со следующим содержимым:
$ cat .env
PYTHONPATH=${PYTHONPATH}:src
Теперь запускаю мое приложение с чем-то вроде
$ pipenv run python -m package.subpackage.app
кажется, работает нормально из моей папки проекта, а также из его подпапок.
Примечание (хотя это не хороший/чистый способ сделать что-то):
для вашего ModuleNotFoundError: No module named 'src'
проблема... "проблема" в том, что src
(папка) не является пакетом, чтобы исправить это, вы можете легко добавить (пустой) файл __init__.py
внутри src
папка, что делает ее "упаковкой"; что в свою очередь сделает возможным import src.baz
.