通过pipenv自定义模块搜索路径(PYTHONPATH)
我有一个Python项目,包括一个Jupyter笔记本、一个通过pipenv自定义模块搜索路径(PYTHONPATH),python,python-3.x,pythonpath,pipenv,Python,Python 3.x,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
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外壳运行
:
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'
我尝试的一个解决方案是在myproject
下添加一个.env
文件:
PYTHONPATH=${PYTHONPATH}:${PWD}
这得益于pipenv
,但将.env
文件检查到项目的git发行版中会与.env
存储密码等机密的传统用法相冲突——事实上,由于这个原因,Python项目的默认.gitignore
已经排除了.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
等,这也是一个麻烦
我当前的解决方法只是添加一个符号链接:
myproject
├── Pipfile
├── Pipfile.lock
├── bin
│ ├── bar.py
│ ├── foo.py
│ └── src -> ../src
└── src
├── baz.py
└── qux.py
这是可行的,我认为它的好处是透明,但似乎应该有某种方法来利用pipenv
来解决同样的问题
是否有一种可移植的、可分发的方式将这些模块放在搜索路径上?我不确定是否有一个完美的解决方案,但为了显式而不是隐式(),我决定在运行任何脚本之前签入一个需要来源的文件。这是一个额外的手动步骤,但您可以将其放入一个Makefile中 env.sh
export PYTHONPATH=${PYTHONPATH}:${PWD}
Makefile
bar:
source env.sh && pipenv run python scripts/bar.py
.PHONY: migrate
该解决方案与Go采用的方法有点类似,它的GOPATH
我认为其他解决方案没有那么好:
旨在解决依赖关系,我可能错了,但我没有找到任何与pipenv
问题相关的东西PYTHONPATH
- 如果您开始在文件夹中使用其他脚本,链接文件夹将无法很好地扩展
- (来这里寻求答案,结果却给出了答案)
我有一个类似的项目文件夹结构,所以我有同样的问题。
多亏了您的提示,我的解决方案是添加一个与
Pipfile
相同级别的文件.env
,该文件包含以下内容:
$ cat .env
PYTHONPATH=${PYTHONPATH}:src
现在,使用以下内容启动我的应用程序
$ pipenv run python -m package.subpackage.app
从我的项目文件夹和它的子文件夹中似乎可以正常工作
旁注(虽然不是一种好的/干净的做事方式):对于您的
ModuleNotFoundError:没有名为'src'的模块问题
。。。“问题”在于src
(文件夹)不是一个包,为了解决这个问题,您可以轻松地在src
文件夹中添加一个(空的)\uuuuuuuuuuuuuuuuuuuupy
文件,使其成为一个“包”;这反过来又使导入src.baz成为可能
(稍后编辑)实际上,这在
sys.path
中添加了一条记录/${PYTHONPATH}
,这是无用的,因此.env
文件的正确内容应该只有PYTHONPATH=src
我得到了与您相同的.env
想法。但是我的路径的值实际上是${PYTHONPATH}:${PWD}
。为什么对你有用?@Pranasas我不知道,对不起。尝试问一个新问题。pipenv自动加载.env文件,而不是创建bash脚本,您只需在运行pipenv命令之前设置env变量即可。使用您在Makefile中使用的同一行:PYTHONPATH=${PYTHONPATH}:${PWD}pipenv运行python脚本/bar.py
不是为了吹毛求疵,但是这个解决方案(或任何类似的解决方案)如何比只运行export PYTHONPATH=。
?您正在制作一个单独的脚本并创建一个Makefile来保存一行代码?这看起来非常不符合Python:)这是最方便的非变通答案。在我看来,.env文件(env vars)是最好的解决方案。3小时后,我找到了你的答案,谢谢你,兄弟,很简单:)