通过pipenv自定义模块搜索路径(PYTHONPATH)

Dav*_*les 18 python pythonpath python-3.x pipenv

我有一个Python项目,包括一个Jupyter笔记本,一个bin目录中的几个脚本和一个目录中的模块src,依赖于Pipfile:

myproject
??? myproject.ipynb
??? Pipfile
??? Pipfile.lock
??? bin
?   ??? bar.py
?   ??? foo.py
??? src
    ??? baz.py
    ??? qux.py
Run Code Online (Sandbox Code Playgroud)

脚本foo.pybar.py使用标准shebang

#!/usr/bin/env python
Run Code Online (Sandbox Code Playgroud)

并可以运行pipenv shell:

mymachine:myproject myname$ pipenv shell
(myproject-U308romt) bash-3.2$ bin/foo.py
foo
Run Code Online (Sandbox Code Playgroud)

但是,我无法src从脚本中轻松访问模块.如果我加

import src.baz as baz
Run Code Online (Sandbox Code Playgroud)

foo.py时,我得到:

ModuleNotFoundError: No module named 'src'
Run Code Online (Sandbox Code Playgroud)

我试过的一个解决方案是在下面添加一个.env文件myproject:

PYTHONPATH=${PYTHONPATH}:${PWD}
Run Code Online (Sandbox Code Playgroud)

此作品感谢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.
Run Code Online (Sandbox Code Playgroud)

或者,我可以移动srcbin,但随后Jupyter笔记本电脑将不得不引用模块,bin.src.baz等等,这也是一个麻烦.

我目前的解决方法是添加符号链接:

myproject
??? Pipfile
??? Pipfile.lock
??? bin
?   ??? bar.py
?   ??? foo.py
?   ??? src -> ../src
??? src
    ??? baz.py
    ??? qux.py
Run Code Online (Sandbox Code Playgroud)

这是有效的,我认为有透明的好处,但似乎应该有一些方法pipenv来解决同样的问题.

是否有可移植的,可分发的方式将这些模块放在搜索路径上?

cha*_*lax 12

我不确定这是一个完美的解决方案,但为了明确而不是隐含(PEP 20),我决定在运行任何脚本之前签入一个需要获取的文件.这是一个额外的手动步骤,但您可以将其放在Makefile中.

env.sh

export PYTHONPATH=${PYTHONPATH}:${PWD}
Run Code Online (Sandbox Code Playgroud)

Makefile文件

bar:
    source env.sh && pipenv run python scripts/bar.py
.PHONY: migrate
Run Code Online (Sandbox Code Playgroud)

解决方案有点类似于Go采用的方法GOPATH.

我认为其他解决方案不太好:

  • pipenv旨在解决依赖关系,我可能是错的,但我没有找到任何与问题有关的问题PYTHONPATH.
  • 如果您开始使用其他脚本文件夹,链接文件夹将无法很好地扩展.

  • 除了创建bash脚本外,您还可以在运行pipenv的命令之前设置环境变量。使用在Makefile中使用的同一行:`PYTHONPATH = $ {PYTHONPATH}:$ {PWD} pipenv运行python scripts / bar.py` (2认同)

Loh*_*HAR 12

(来这里是为了一个答案,最终给出了一个答案)

我有一个类似的项目文件夹结构,所以我遇到了同样的问题。
感谢您的提示,我的解决方案是添加一个与以下内容.env相同级别的文件Pipfile

$ cat .env
PYTHONPATH=${PYTHONPATH}:src
Run Code Online (Sandbox Code Playgroud)

现在,用类似的东西启动我的应用程序

$ pipenv run python -m package.subpackage.app
Run Code Online (Sandbox Code Playgroud)

从我的项目文件夹内部以及它的子文件夹中似乎都可以正常工作。

旁注(虽然不是一个好的/干净的做事方式):
对于你的ModuleNotFoundError: No module named 'src'问题......“问题”是src(文件夹)不是一个包,为了解决这个问题,你可以轻松地添加一个(空)__init__.py文件src夹内的文件,从而使其成为“包”;这反过来将成为import src.baz可能。

(后来编辑)
事实上,这增加了一个记录<project_folder>/${PYTHONPATH}sys.path,这是没用的,所以正确内容.env的文件应该是唯一的PYTHONPATH=src

  • 3小时后我找到了你的答案,谢谢兄弟,这么简单:) (2认同)