python - 系统上的软件包更新会影响虚拟环境?
问题描述
我在虚拟环境中。我在我的活动终端中验证了这一点,which python
并且可以确认我实际上是在虚拟环境中。打印pip list
,根据官方文档,应该列出这个虚拟环境中的包。这是一个输出:
Package Version
---------------------------------- -------------------
alabaster 0.7.10
anaconda-client 1.6.5
... (truncated)
pip 10.0.1
You are using pip version 10.0.1, however version 18.0 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
当我启动另一个终端时,这次确保我不在那个虚拟环境中并继续升级pip
:
pip install --upgrade pip
这样做后,我验证了我pip
系统上的包已更新到版本 18.0。这是令人困惑的部分:我切换回虚拟环境并使用,我的虚拟环境pip list
中的 pip 版本现在是 pip 18.0。
为什么在该环境之外升级 pip 版本随后从 10.0.1 更新我的虚拟环境中的 pip?我是否误解了虚拟环境的工作原理?我对python并不陌生,但没有使用过虚拟环境,所以如果它是非常基础的东西,请原谅我。据我了解,使用虚拟环境的主要价值是我可以升级我的系统范围的包(例如 pip、flask 等),而不会影响我的虚拟环境中的任何更改。虚拟环境应该是孤立的环境吗?
如果重要的话,我使用的是默认venv
而不是virtualenvwrapper
任何其他包装工具。
解决方案
问题
tl; dr:问题出在 conda 上。我使用 conda,显然这会导致在通过创建的虚拟环境中管理和安装软件包时出现一些问题,venv
因为本地实例pip
不存在。
解决方案 A:conda install -n myenv pip
其中myenv
指的是您的虚拟环境的名称
解决方案 B:使用conda list
,conda create
以与 conda 100% 兼容的方式处理环境
/结束 tl;博士
这是问题的细分。当我使用 anaconda 的 python 版本时,我决定查看我环境中的软件包列表;假设我打电话给pip freeze
or pip list
,我是否在虚拟环境中都没有关系。site-packages
它从 conda 的相应文件夹返回完全相同的包列表。
当我在虚拟环境中时, runningwhich python
似乎确实指向 python 实例的隔离版本(acco
是该实例的名称):
(acco) Samuels-MacBook-Pro:Accomplish Samuel$ which python
/Users/Samuel/Dropbox/Projects/Python/Acco/acco/bin/python
然而,在这个虚拟环境中,运行pip list
还是pip list --local
会引用同一组包——那是因为它仍然指向 conda 版本的包目录(是的,即使在虚拟环境中也是如此)。
具体来说,无论有无,在虚拟环境内部或外部,pip list
指向安装在/anaconda3/lib/../site-packages
目录中的包:
import sys
sys.prefix
'/Users/Samuel/anaconda3'
import site
site.getsitepackages()
['/Users/Samuel/anaconda3/lib/python3.6/site-packages']
真正有问题的部分是,在虚拟环境中,您基本上没有安装任何库。如果您尝试安装的任何软件包已经存在于 conda 的目录中,则从requirements.txt' using
pip install -r requirements.txt or just installing packages at all using plain old
pip install 安装将不起作用。相反,您会收到一条看起来不像错误的消息,并且它就停在那里。您尝试安装的软件包未安装到本地目录中。
# same as pip install Flask==0.12.2
pip install -r requirements.txt
Requirement already satisfied: Flask==0.12.2 in /Users/Samuel/anaconda3/lib/python3.6/site-packages (from -r requirements.txt (line 1)) (0.12.2)
Requirement already satisfied: Werkzeug>=0.7 in /Users/Samuel/anaconda3/lib/python3.6/site-packages (from Flask==0.12.2->-r requirements.txt (line 1)) (0.12.2)
Requirement already satisfied: Jinja2>=2.4 in /Users/Samuel/anaconda3/lib/python3.6/site-packages (from Flask==0.12.2->-r requirements.txt (line 1)) (2.9.6)
Requirement already satisfied: itsdangerous>=0.21 in /Users/Samuel/anaconda3/lib/python3.6/site-packages (from Flask==0.12.2->-r requirements.txt (line 1)) (0.24)
Requirement already satisfied: click>=2.0 in /Users/Samuel/anaconda3/lib/python3.6/site-packages (from Flask==0.12.2->-r requirements.txt (line 1)) (6.7)
Requirement already satisfied: MarkupSafe>=0.23 in /Users/Samuel/anaconda3/lib/python3.6/site-packages (from Jinja2>=2.4->Flask==0.12.2->-r requirements.txt (line 1)) (1.0)
提醒一下,我们仍然在我们的虚拟环境 ( ../Dropbox/Projects/Python/Acco/acco/bin/python
) 中使用 python 执行您的 python 命令,而不是 conda 发行版。此虚拟环境在其隔离文件夹中没有包lib
,并且您无法将任何库安装到其中,因为pip
“要求已满足”消息将停止并退出(或终止其尝试)。
这意味着在该虚拟环境中,尝试运行具有依赖项的 python 脚本或应用程序肯定会失败。从上面的示例构建,您的 Flask 应用程序app.py
将无法运行,因为它找不到flask
. 不用说,因为你的虚拟环境没有包,它不会让你安装任何包。
解决方案
解决方案是,如果您使用的是 python 的 conda 发行版,请检查您已安装在系统上的软件包,conda list
而不是pip list
最大程度地保持一致性。
(acco) Samuels-MacBook-Pro:Acco Samuel$ conda list
# packages in environment at /Users/Samuel/anaconda3:
#
# Name Version Build Channel
_ipyw_jlab_nb_ext_conf 0.1.0 py36h2fc01ae_0
_r-mutex 1.0.0 mro_2
alabaster 0.7.10 py36h174008c_0
anaconda custom py36ha4fed55_0
请注意,它conda
告诉您列出库的环境。在这个阶段:
- 使用停用环境
deactive
- 使用 制作虚拟环境
conda create --name acco python=3.6.3 flask sqlite
,这里我们使用acco
虚拟环境的名称、特定版本的 python 以及可选的其他一些依赖项 - 使用激活环境
source activate acco
现在,当你conda list
再次这样做时,在你的虚拟环境中:
# packages in environment at /Users/Samuel/anaconda3/envs/acco:
#
# Name Version Build Channel
ca-certificates 2018.03.07 0
certifi 2018.8.13 py36_0
click 6.7 py36hec950be_0
flask 1.0.2 py36_1
如果您想使用老式requirement.txt
文件管理应用程序的依赖项,那么最简单的方法是conda list --export > requirements.txt
. 从这一点开始,使用conda list
代替pip list
和使用conda create
以及source activate
代替其venv
对应物。
要在您的环境中使用 pip,请在终端窗口或 Anaconda 提示符中运行:
conda install -n acco pip source activate acco pip <pip_subcommand>
该解决方案也有效。按照上面的步骤,我最终得到:
(acco) Samuels-MacBook-Pro:Accomplish Samuel$ pip list
Package Version
------------ ---------
certifi 2018.8.13
click 6.7
Flask 1.0.2
itsdangerous 0.24
Jinja2 2.10
MarkupSafe 1.0
pip 10.0.1
setuptools 40.0.0
Werkzeug 0.14.1
wheel 0.31.1
作为奖励,我仔细检查了以这种方式创建的 conda 环境是否能够处理pip list
or pip install
: 相同的错误。但是,当使用conda update
(例如conda update sqlite
:)conda install
或任何 conda-counterpart 代码时,它们都按预期工作。在您的本地环境中更新sqlite
完全更新该副本,sqlite
而不是您的 anaconda 系统中的副本。哇!
推荐阅读
- algorithm - 带有 If 语句的循环的时间复杂度
- flutter - 如何使用 url 方案向信使发送消息?
- java - 对 JVM 内存消耗进行基准测试,类似于 Android 操作系统的基准测试
- java - SpringBoot中的未授权
- angular - ASP.NET Core Web 应用程序:升级到 Angular 9 - 错误 es2015 为 esm2015
- c# - 如何将简单字符串对象绑定到 Xamarin Forms 中的标签文本?
- python - 运行 setx OPENCV_VIDEOIO_PRIORITY_MSMF 0 后,vscode 终端在多线程错误后冻结
- mysql - 为什么 CakePHP 4 CLI 不能通过 PDO 连接到 MySQL 数据库?
- python - 无法在 Python 上安装 beautifulsoup 和 requests
- c# - 在中间件中接收来自 StatusCode 的消息