Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过pipenv自定义模块搜索路径(PYTHONPATH)_Python_Python 3.x_Pythonpath_Pipenv - Fatal编程技术网

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

通过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

我有一个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外壳运行

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小时后,我找到了你的答案,谢谢你,兄弟,很简单:)