通过 pipenv 自定义模块搜索路径 (PYTHONPATH) [英] Customize module search path (PYTHONPATH) via pipenv
问题描述
我有一个 Python 项目,它包含一个 Jupyter 笔记本、bin
目录中的几个脚本和 src
目录中的模块,以及 Pipfile<中的依赖项代码>:
I have a Python project consisting of a Jupyter notebook, several scripts in a bin
directory and modules in a src
directory, with dependencies in a Pipfile
:
myproject
├── myproject.ipynb
├── Pipfile
├── Pipfile.lock
├── bin
│ ├── bar.py
│ └── foo.py
└── src
├── baz.py
└── qux.py
脚本foo.py
和bar.py
使用标准shebang
The scripts foo.py
and bar.py
use the standard shebang
#!/usr/bin/env python
并且可以使用 pipenv shell
运行:
and can be run with pipenv shell
:
mymachine:myproject myname$ pipenv shell
(myproject-U308romt) bash-3.2$ bin/foo.py
foo
但是,我无法从脚本轻松访问 src
中的模块.如果我添加
However, I can't easily access the modules in src
from the scripts. If I add
import src.baz as baz
到foo.py
,我得到:
ModuleNotFoundError: No module named 'src'
我尝试过的一种解决方案是在 myproject
下添加一个 .env
文件:
One solution I tried is to add a .env
file under myproject
:
PYTHONPATH=${PYTHONPATH}:${PWD}
这要归功于 pipenv
的 自动加载.env
,但是将.env
文件检查到项目的git分发中会与传统使用 .env
来存储密码等秘密——事实上,我默认的 Python 项目的 .gitignore
已经排除了 .env
这个原因.
This works thanks to pipenv
's automatic loading of .env
, but checking the .env
file into the git distribution of the project would collide with the traditional use of .env
to store secrets such as passwords -- in fact, my default .gitignore
for Python projects already excludes .env
for just this reason.
$ 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 notebook 必须将模块引用为 bin.src.baz
等等,这也很麻烦.
Alternatively, I could move src
under bin
, but then the Jupyter notebook would have to reference the modules as bin.src.baz
etc., which is also a hassle.
我目前的解决方法只是添加一个符号链接:
My current workaround is just to add a symlink:
myproject
├── Pipfile
├── Pipfile.lock
├── bin
│ ├── bar.py
│ ├── foo.py
│ └── src -> ../src
└── src
├── baz.py
└── qux.py
这行得通,我想它有透明的好处,但似乎应该有某种方法可以利用 pipenv
来解决同样的问题.
This works, and I suppose has the benefit of being transparent, but it seems like there should be some way to leverage pipenv
to solve the same problem.
是否有一种可移植、可分发的方式将这些模块放在搜索路径上?
Is there a portable, distributable way to put these modules on the search path?
推荐答案
我不确定是否有完美的解决方案,但为了显式而不是隐式(PEP 20),我决定签入一个需要之前获取的文件运行任何脚本.这是一个额外的手动步骤,但您可以将其放入 Makefile 中.
I'm not sure there's a perfect solution for this, but in the interest of being explicit rather than implicit (PEP 20), I've decided to check in a file that needs to be sourced before running any script. This is one extra manual step but you can put this in a Makefile for instance.
env.sh
export PYTHONPATH=${PYTHONPATH}:${PWD}
Makefile
bar:
source env.sh && pipenv run python scripts/bar.py
.PHONY: migrate
该解决方案有点类似于 Go 对其 GOPATH
所采用的方法.
The solution is a bit similar to the approach Go takes with its GOPATH
.
我认为其他解决方案没有那么好:
I think the other solutions are not as good:
pipenv
旨在解决依赖关系,我可能是错的,但我没有找到与PYTHONPATH
问题相关的任何内容.- 如果您开始使用其他脚本文件夹,链接文件夹将无法很好地扩展.
pipenv
aims to solve dependencies, I could be wrong but I did not find anything related to the problem of thePYTHONPATH
.- Linking folders won't scale really well if you start having other scripts folder.
这篇关于通过 pipenv 自定义模块搜索路径 (PYTHONPATH)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!