为什么 pipenv 还在使用全局的 jupyter (/usr/bin/python3) 而没有封装在自己的环境中?

Why is pipenv still using the global jupyter (/usr/bin/python3) and not encapsulated on its own environment?

我创建了一个 test 文件夹,然后在这个测试文件夹中做了 pipenv install

之后,我运行pipenv shell激活我的新环境。

目前一切顺利...

然后我运行pip freeze

这个刚刚创建的虚拟机中没有jupyter,但是如果我输入jupyter notebook,它会打开jupyter o_O

在jupyter notebook上我运行import sys然后print(sys.executable)检查环境是否正常,但实际上运行我在pipenv之外的全局环境。虽然,它是 运行 !which python 命令中正确的 Python。

任何人都可以告诉我我必须做什么才能使 pipenv 环境隔离(封装)以处理不同的项目吗?

首先,pipenv 和安装包的典​​型工作流程是:

  1. 设置系统范围 python 和虚拟环境模块(即 pipenv
  2. 创建您的项目文件夹(即 test
  3. 在那里创建一个虚拟环境(即 pipenv shellpipenv install
    • 您可以传入特定的 python 版本(如果您安装了多个版本则很重要)
    • pipenv,传--python=/path/to/python3
  4. 安装您的软件包(即 pipenv install jupyter

现在 jupyter。安装它时,它会添加一个 bin/jupyter 可执行文件。由于您已经在系统范围 python 中安装了它,因此它也可以在系统范围内使用(甚至在 pipenv shell 内)。

~$ python3.8 -m pip install jupyter
...
Requirement already satisfied: jupyter in /usr/local/lib/python3.8/site-packages (1.0.0)

~$ which jupyter
/usr/local/bin/jupyter

~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

调用 jupyter 应该可以在 /usr/local/bin 中找到它。在 pipenv shell 内,它不会阻止您访问系统范围内的 bin 内容(因为那会很烦人)。所以在 pipenv shell 中,您的 jupyter 安装仍然可用:

TEMP$ pipenv shell

(TEMP) TEMP$ pip list
Package    Version
---------- -------
pip        20.2.4
setuptools 50.3.2
wheel      0.35.1

(TEMP) TEMP$ echo $PATH
/Users/me/.venvs/TEMP-S6DFgeUE/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

(TEMP) TEMP$ which jupyter
/usr/local/bin/jupyter

(TEMP) TEMP$ jupyter --version   # Can be invoked here even if not in pip list

pipenv shell 所做的是在你的 $PATH 前面添加另一个 /bin 文件夹,所以你在这个环境中安装的包并添加 bin 东西将会是无障碍。调用它们应该首先从虚拟环境中找到它。你发生的事情是,调用 jupyter 并没有在虚拟环境的 bin (/Users/me/.venvs/TEMP-S6DFgeUE/bin) 中找到它,而是在系统端 bin (/usr/local/bin) 中找到它。这就是 为什么 即使不在您的虚拟环境中安装 jupyter,它仍然可以访问。

这通常适用于安装 bin 东西的软件包。

现在,该怎么办。正如我在开始时提到的,您应该(尽可能)避免在系统范围内安装东西 python。只在虚拟环境中(尽可能多地)安装东西。

因此,对于您的情况,从在您的虚拟环境中安装 jupyter 开始:

(TEMP) TEMP$ pipenv install jupyter
Installing jupyter...
...

(TEMP) TEMP$ which jupyter
/Users/me/.venvs/TEMP-S6DFgeUE/bin/jupyter

(TEMP) TEMP$ jupyter --version  # Check that it works

(TEMP) TEMP$ ls $(pipenv --venv)/lib/python3.8/site-packages | grep jupyter
jupyter-1.0.0.dist-info
jupyter.py
jupyter_client
jupyter_client-6.1.7.dist-info
jupyter_console
jupyter_console-6.2.0.dist-info
jupyter_core
jupyter_core-4.7.0.dist-info
jupyterlab_pygments
jupyterlab_pygments-0.1.2.dist-info

当您安装它时,调用 jupyter 现在应该可以从虚拟环境 bin 中找到它。它还应该在虚拟环境的站点包文件夹中添加 jupyter 东西。

为了确认您的虚拟环境中的 jupyter 正在运行,我强烈建议卸载系统范围的 jupyter。请注意,仅执行 pip uninstall jupyter 是不够的,您需要完全卸载它以删除 /usr/local/bin/jupyter(参见:How to uninstall jupyter):

python3.8 -m pip uninstall -y jupyter jupyter_core jupyter-client jupyter-console jupyterlab_pygments notebook qtconsole nbconvert nbformat

然后回到你的pipenv shell,并确认你只有在你的虚拟环境中有jupyter

~$ jupyter --version
-bash: jupyter: command not found

~$ cd TEMP
TEMP$ pipenv shell
Launching subshell in virtual environment...
...

(TEMP) TEMP$ jupyter --version
jupyter core     : 4.7.0
jupyter-notebook : 6.1.5
qtconsole        : 5.0.1
ipython          : 7.19.0
ipykernel        : 5.3.4
jupyter client   : 6.1.7
jupyter lab      : not installed
nbconvert        : 6.0.7
ipywidgets       : 7.5.1
nbformat         : 5.0.8
traitlets        : 5.0.5

(TEMP) TEMP$ which jupyter
/Users/me/.venvs/TEMP-S6DFgeUE/bin/jupyter