系统上的软件包更新会影响虚拟环境吗?

时间:2018-08-19 15:56:57

标签: python conda virtual-environment

我在虚拟环境中。我使用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版本现在是18.0点。

为什么在该环境之外升级pip版本会随后从10.0.1完全更新我的虚拟环境中的pip?我是否误解了虚拟环境的工作原理?我对python并不陌生,但是没有使用虚拟环境,所以如果这是非常基本的内容,请原谅我。据我了解,使用虚拟环境的主要价值在于,我可以升级系统范围的软件包(例如pip,flask等),而不会在虚拟环境中影响任何更改。虚拟环境应该完全是孤立的环境吗?

如果有关系,我使用的是默认的venv,而不是virtualenvwrapper或任何其他包装工具。

1 个答案:

答案 0 :(得分:0)

问题

tl; dr :问题出在conda上。我使用conda,显然会在通过venv创建的虚拟环境中管理和安装软件包时引起一些问题,因为不存在pip的本地实例。

解决方案A:conda install -n myenv pip,其中myenv是指您的虚拟环境的名称

解决方案B:使用conda listconda create以与conda 100%兼容的方式在环境中工作

/结束tl; dr

这是问题的细目。当我使用anaconda的python版本时,我决定查看自己环境中的软件包列表。假设我要打电话给pip freezepip list,无论我是否在虚拟环境中都没关系。它从conda的相应site-packages文件夹中返回完全相同的软件包列表。

当我在虚拟环境中时,运行which python似乎指向一个隔离的python实例版本(acco是该实例的名称):

(acco) Samuels-MacBook-Pro:Accomplish Samuel$ which python
/Users/Samuel/Dropbox/Projects/Python/Acco/acco/bin/python 

但是,在此虚拟环境中,运行pip listpip 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会因“ requirement included”消息而停止并退出(或终止其尝试) )。

这意味着在该虚拟环境中,尝试运行具有依赖项的python脚本或应用程序肯定会失败。根据上述示例构建的Flask应用app.py无法运行,因为找不到flask。毋庸置疑,由于您的虚拟环境没有软件包,因此不会安装任何软件包。


解决方案

解决方案是,如果您使用的是conda发行版的python,请使用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会告诉您列出库的环境。在这个阶段:

  1. 使用deactive停用环境
  2. 使用conda create --name acco python=3.6.3 flask sqlite创建虚拟环境,这里我们使用acco作为虚拟环境的名称,特定版本的python以及其他可选的依赖项
  3. 使用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 createsource activate代替其venv

anaconda's main documentation建议:

  

要在您的环境中,终端窗口或Anaconda中使用pip   提示,运行:

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 listpip install:相同的错误。但是,当使用conda update(例如:conda update sqlite),conda install或任何conda对应代码时,它们都可以完全正常工作。在本地环境中更新sqlite会完全更新sqlite的那个副本,而不是anaconda系统中的那个副本。哇!

相关问题