我想避免在默认环境中“意外”工作。
我希望始终有一个等效的requirements.txt
或package.json
文件可用,既可以清楚地将一个项目与另一个项目分开,又可以让我轻松地回头看看已安装了什么(和它的版本)。
但是我主要在数据科学/分析领域工作,并且主要使用Python。
因此,我使用Anaconda,pip和Homebrew(我有Mac)。 仅依靠一个程序包管理器将是很棒的,许多人拥护one method或another来完成此任务。真相是,截至目前(2018年9月),不可能在任何广度的主题上开展工作,并且至少要避免某种混杂。
将目光放得更低些,更现实一些,我只想确保在任何可能的地方都没有没有默认环境,以使其更清洁,更轻松地与他人一起进行项目。
据我所知,Homebrew中根本没有环境的概念。 Conda当然有环境,但是在创建其他任何环境之前,它首先会设置默认环境。
是否可以在没有任何默认环境的情况下安装 Anaconda ,这样我将总是必须source activate <my_env>
?如果是这样,我该怎么办?
除此以外,什么是实现我想要的最好的建议,那就是在不确定我的依赖是什么的环境中永远不要偶然工作,因为我认识到我主要是在说话,但是不只是关于使用Python?
(请不要建议我在安装软件包时要“小心”。是的,我理解这一点。但是,我试图通过尽可能困难或不可能的错误选择来抢先小心。例如,如果我没有默认环境,那么pip
甚至在我找到环境之前都无法工作,因为在我的正常环境中找不到该环境。)
答案 0 :(得分:2)
我认为,最好的选择是简单地使用虚拟环境并在必要时安装依赖项,然后在工作进行时随便签入和签出虚拟环境。您可以在处理不同项目时创建不同的虚拟环境,并将其相应的requirements.txt文件保留在安装虚拟环境时python创建的目录中。假设我将python3.5.2作为我的常规python软件包(因为这样做了)。
使用python3.5,让我们进入一个虚拟环境,只不过是裸露的python3.5(没有安装依赖项)。为此:
[dkennetz@node venv_test]$ python -m venv my_SO_project
[dkennetz@node venv_test]$ ls
my_SO_project
所以我们看到,python创建了一个目录来存放我的虚拟环境,但是我的虚拟环境并未被用作默认的python。为此,我们必须将其激活:
[dkennetz@node venv_test]$ source ./my_SO_project/bin/activate
所以我的外壳现在看起来像这样:
(my_SO_project) [dkennetz@nodecn201 venv_test]$
我们在这里时,让我们看看我们的需求是什么样的:
(my_SO_project) [dkennetz@nodecn201 venv_test]$ pip freeze > requirements.txt
(my_SO_project) [dkennetz@nodecn201 venv_test]$ ls -alh
drwxr-x--- 3 dkennetz blank 4.0K Oct 9 09:52 .
drwxr-x--- 93 dkennetz root 16K Oct 9 09:40 ..
drwxr-x--- 5 dkennetz blank 4.0K Oct 9 09:47 my_SO_project
-rwxr-x--- 1 dkennetz blank 0 Oct 9 09:47 requirements.txt
使用空白隐藏组名,但是正如我们所看到的,我们的requirements.txt文件大小为空,这意味着该虚拟环境没有依赖性。纯粹是python3.5。现在,让我们继续安装熊猫,看看我们的依赖关系如何变化。
(my_SO_project) [dkennetz@nodecn201 venv_test]$ pip install pandas
(my_SO_project) [dkennetz@nodecn201 venv_test]$ pip freeze > requirements.txt
(my_SO_project) [dkennetz@nodecn201 venv_test]$ more requirements.txt
numpy==1.15.2
pandas==0.23.4
python-dateutil==2.7.3
pytz==2018.5
six==1.11.0
(my_SO_project) [dkennetz@nodecn201 venv_test]$ wc -l requirements.txt
5 requirements.txt
假设我们已经在环境中编写了一些代码,我们不再想要做更多的工作,因此我们进行了最后一个pip冻结> Requirements.txt,然后离开:
(my_SO_project) [dkennetz@nodecn201 venv_test]$ deactivate
[dkennetz@nodecn201 venv_test]$ pip freeze > requirements_normal.txt
[dkennetz@nodecn201 venv_test]$ wc -l requirements_normal.txt
82 requirements_normal.txt
弹出更多依赖关系,但是在我们的正常环境中没有任何变化,在我们的虚拟环境中也没有变化。现在,假设我们已经休息了一天,并希望回到昨天创建的SO_project。好吧,很简单:
[dkennetz@nodecn201 venv_test]$ ls -alh
drwxr-x--- 3 dkennetz blank 4.0K Oct 9 10:01 .
drwxr-x--- 93 dkennetz root 16K Oct 9 09:40 ..
drwxr-x--- 5 dkennetz blank 4.0K Oct 9 09:47 my_SO_project
-rwxr-x--- 1 dkennetz blank 77 Oct 9 09:56 requirements.txt
-rwxr-x--- 1 dkennetz blank 1.3K Oct 9 10:01 requirements_normal.txt
[dkennetz@nodecn201 venv_test]$ source ./my_SO_project/bin/activate
(my_SO_project) [dkennetz@nodecn201 venv_test]$
让我们看看我们从何处中断(我们应该只安装熊猫,让我们覆盖旧的requirements_file):
(my_SO_project) [dkennetz@nodecn201 venv_test]$ pip freeze > requirements.txt
(my_SO_project) [dkennetz@nodecn201 venv_test]$ more requirements.txt
numpy==1.15.2
pandas==0.23.4
python-dateutil==2.7.3
pytz==2018.5
six==1.11.0
很酷,所以现在我们知道我们就是我们离开的地方。只是一个公平的警告,我在根python软件包上安装了熊猫,但我没有awscli(amazon Web服务命令行界面)。假设我出于某些原因想要在我的包裹中
(my_SO_project) [dkennetz@nodecn201 venv_test]$ pip install awscli
(my_SO_project) [dkennetz@nodecn201 venv_test]$ pip freeze > requirements.txt
(my_SO_project) [dkennetz@nodecn201 venv_test]$ wc -l requirements.txt
15 requirements.txt
(my_SO_project) [dkennetz@nodecn201 venv_test]$ deactivate
[dkennetz@nodecn201 venv_test]$ ls
my_SO_project requirements.txt requirements_normal.txt
[dkennetz@nodecn201 venv_test]$ pip freeze > requirements_normal.txt
[dkennetz@nodecn201 venv_test]$ wc -l requirements_normal.txt
82 requirements_normal.txt
所以我们现在看到安装awscli并没有改变我们的python软件包,但是它改变了我们的venv:
[dkennetz@nodecn201 venv_test]$ more requirements_normal.txt
appdirs==1.4.3
arrow==0.7.0
attrdict==2.0.0
avro-cwl==1.8.4
...
[dkennetz@nodecn201 venv_test]$ more requirements.txt
awscli==1.16.29
botocore==1.12.19
colorama==0.3.9
docutils==0.14
...
最后,假设您已经完全在VM内开发了一个超酷的数据科学软件包,并且已使其可点安装。快速简便的方法是:
[dkennetz@nodecn201 venv_test]$ pip install -r requirements.txt
现在,每次“ pip”安装“新程序”时,您都可以将其用作软件包列表,而且更好的是,您知道需要它的每个python软件包,因为这些是您环境中唯一包含的软件包。 / p>
所有这些,没有理由您每次与新人一起开始新项目时都不能这样做。而且,如果您想在使用过的每个虚拟环境中安装anaconda,请正常安装anaconda:
[dkennetz@nodecn201 venv_test]$ ./Anaconda-1.6.0-Linux-x86_64.sh
[dkennetz@nodecn201 venv_test]$ source /home/dkennetz/anaconda3/bin/activate
#You will be in your anaconda environment now
(base) [dkennetz@nodecn201 venv_test]$ pip freeze > anaconda_reqs.txt
假设您在第一个开始后立即启动了my_SO_project2,并希望确保该程序包中有anaconda。以与上次相同的方式创建新的虚拟视频。一旦进入,只需安装anaconda所需的所有依赖项,您将拥有一个全新的anaconda虚拟环境:
(my_SO_project2) [dkennetz@nodecn201 venv_test]$ pip install -r anaconda_reqs.txt
您的新venv从一个全新的环境开始,除了安装Anaconda之外什么都没有。
我希望这可以澄清我在评论中所说的话,对您有所帮助。
答案 1 :(得分:2)
首先,我要从系统中删除python 。
编辑:正如评论中指出的那样,在macOS中这不是一个好主意。我只会在Docker容器中使用这种方法。但是,如果您确实有docker,则可以为每个项目生成一个Docker,然后进行设置。
命令which python
应该不返回任何内容。
安装miniconda,它是conda软件包管理器以及裸露的python。
为每个项目创建环境
conda create -n myproject python=3.6
由于没有默认的Python,因此需要在需要使用该环境的任何时候提供源环境
source activate myproject
请注意,从技术上讲,miniconda创建一个默认的env,称为“ base”(无法删除)。但是和其他任何环境一样,它没有被激活,因此您仍然没有任何python(如果确实按照建议删除了),并且不会意外地运行“错误的” python。
答案 2 :(得分:1)
这个问题似乎一次要问很多不同的问题。
是否可以在没有任何默认环境的情况下安装Anaconda
如上所述,conda
将始终具有基本环境,该环境实质上是默认环境。
因此,我使用Anaconda,pip和Homebrew(我有Mac)。
如前所述,这里的最大区别是Homebrew用于系统范围的安装。您应将pip
和conda
视作每个项目的安装,正如我将在回答中解释的那样:
认识到我主要是在谈论而不是仅仅在谈论使用Python,什么才是实现我想要的最好的建议,那就是永远不要在不清楚依赖项的环境中意外工作?
我希望始终有一个等效于requirements.txt或package.json文件的文件,既可以清楚地将一个项目与另一个项目分开,又可以让我轻松地回头看看安装了什么(及其版本) )。
在数据科学领域工作了多年之后,这是我确定的解决方案,可以解决您的所有问题。
(在Mac上)通过Homebrew安装所有系统级工具,但请您帮个忙,并尝试将其限制为“通用”工具,例如GNU工具(例如wget
,{{1 }})或其他不会在每个项目中更改的东西和/或在整个系统范围内更好地安装的其他东西(例如Vagrant,Docker,PostgreSQL
对于每个项目,都有一个专用的包装器脚本,该脚本将tree
安装在当前目录中。注意,这里我并不是要安装全局conda
并使用conda环境,而是要在每个项目中实际安装一个新的conda。这将很好用,因为在包装脚本中,您将包含详细的版本锁定的conda安装命令集,以安装所需的所有软件包的确切版本。
此外,您的包装器脚本将包含将此conda放入conda
并清除或覆盖对任何其他系统Python的持久引用所必需的系统环境修改。 $PATH
能够安装大量的非Python软件包,因此这将尽可能地照顾您的非Python软件依赖性。这包括R安装和许多R软件包(对于Bioconductor之类的东西,由于版本控制功能更强,因此比“香草”方式安装更安全)。
对于必须与conda
一起安装的软件包,请不要担心,因为每个pip
安装都附带了自己的conda
安装。因此,您可以在pip
中pip install
,并且这些软件包将单独保留在conda
中。您的conda
命令也将被版本锁定,如果您愿意,可以使用pip install
,以确保该命令是可复制的。
requirements.txt
实例,您将使用上述包装器脚本来包装您在项目中使用的所有命令来运行软件。如果您需要进行交互工作,则只需从包装脚本中调用conda
,它将使您进入一个交互式bash
进程中,并根据您的环境从预先填充的包装脚本中进行操作。 在实践中,我更喜欢将GNU bash
与Makefile一起使用来完成所有这些事情。我在每个项目目录的根目录下创建一个文件make
,其内容如下所示:
Makefile
现在,当您SHELL:=/bin/bash
UNAME:=$(shell uname)
# ~~~~~ Setup Conda ~~~~~ #
PATH:=$(CURDIR)/conda/bin:$(PATH)
unexport PYTHONPATH
unexport PYTHONHOME
# install versions of conda for Mac or Linux, Python 2 or 3
ifeq ($(UNAME), Darwin)
CONDASH:=Miniconda3-4.7.12.1-MacOSX-x86_64.sh
endif
ifeq ($(UNAME), Linux)
CONDASH:=Miniconda3-4.7.12.1-Linux-x86_64.sh
endif
CONDAURL:=https://repo.continuum.io/miniconda/$(CONDASH)
conda:
@echo ">>> Setting up conda..."
@wget "$(CONDAURL)" && \
bash "$(CONDASH)" -b -p conda && \
rm -f "$(CONDASH)"
install: conda
conda install -y \
conda-forge::ncurses=6.1 \
rabbitmq-server=3.7.16 \
anaconda::postgresql=11.2 \
pip install -r requirements.txt
# start interactive bash session
bash:
bash
run:
python myscript.py
进入项目目录时,只需运行诸如cd
之类的命令来安装所有依赖项,以及诸如make install
之类的命令来运行代码即可该项目。
make run
安装的提示:首先安装所有软件包而不指定任何版本号,然后在全部安装之后返回并添加版本号。这比尝试预先指定它们要容易得多。 最后,如果您的软件依赖项无法以这种方式放入Homebrew或conda或pip中,则需要开始做出一些选择,以选择真正需要的再现性和隔离度。您可能开始研究Docker容器或Vagrant虚拟机(在两种情况下,您都可以将配方保留在项目目录中,并继续使用脚本包装命令来运行代码,以供将来参考)。如果没有conda,pip,Docker或Vagrant的组合,我通常不会遇到任何无法解决的按项目开发的软件。
在真正令人发指的情况下,例如在本地运行RStudio不能很好地与conda中安装的R和libs配合使用,我将承认并出于全球目的蛮力安装所需的软件包,但也尝试重新创建一个隔离的软件包在conda或Docker中版本锁定的R +库实例,并在其中作为脚本运行代码以验证结果是否仍然可以在没有全局参数的情况下重新生成