通过 pipenv 自定义模块搜索路径 (PYTHONPATH) [英] Customize module search path (PYTHONPATH) via pipenv

查看:48
本文介绍了通过 pipenv 自定义模块搜索路径 (PYTHONPATH)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 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.pybar.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 the PYTHONPATH.
  • Linking folders won't scale really well if you start having other scripts folder.

这篇关于通过 pipenv 自定义模块搜索路径 (PYTHONPATH)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆