Conda、Virtualenv、Pipenv都是pyhton包
都是环境管理工具(conda还可以做包管理工具,而且不止应用于python)
以便对不同的程序设置指定版本的python
Conda:任何语言的包、依赖和环境管理——Python、R、Ruby、Lua、Scala、Java、JavaScript、C/C++、FORTRAN 等。
pip:pip 是 Python 的软件包安装程序。
virtualenv
- 安装
pip install virtualenv
- 搭建默认虚拟环境
virtualenv venv
- 搭建指定python版本-虚拟环境
virtualenv -p /usr/bin/python3.6 venv
- 使用,激活
source env/bin/activate
- 停用
deactivate
virtualenvwrapper
virtualenv 的一个最大的缺点就是,每次开启虚拟环境之前要去虚拟环境所在目录下的 bin 目录下 source 一下 activate。这时候virtualenvwrapper出现了,它对不同的虚拟环境使用不同的目录进行管理,并且还省去了每次开启虚拟环境时候的 source 操作,使得虚拟环境更加好用。
pip install virtualenvwrapper
vim ~/.bashrc开始配置virtualenvwrapper:
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
接着执行 source ~/.bashrc(或./zshrc)。
注意:修改.bashrc还是.zshrc取决于你使用的那种 shell。
- workon: 打印所有的虚拟环境;
- mkvirtualenv xxx: 创建 xxx虚拟环境,可以–python=/usr/bin/python3.6 指定python版本;
- workon xxx: 使用 xxx虚拟环境; deactivate: 退出 xxx 虚拟环境;
- rmvirtualenv xxx: 删除 xxx 虚拟环境。
- lsvirtualenv : 列举所有的环境。
- cdvirtualenv: 导航到当前激活的虚拟环境的目录中,比如说这样您就能够浏览它的site-packages。
- cdsitepackages: 和上面的类似,但是是直接进入到 site-packages 目录中。
- lssitepackages : 显示 site-packages 目录中的内容。
pipenv
pipenv 是 Pipfile 主要倡导者、requests 作者 Kenneth Reitz 写的一个命令行工具,主要包含了Pipfile、pip、click、requests和virtualenv,能够有效管理Python多个环境,各种第三方包及模块。
pipenv所解决的问题:
- requirements.txt 依赖管理的局限
- 多个项目依赖不同第三方库、包版本问题
- 依赖分析
pipenv的特性:
-
pipenv集成了pip,virtualenv两者的功能,且完善了两者的一些缺陷。
-
过去用virtualenv管理requirements.txt文件可能会有问题,Pipenv使用Pipfile和Pipfile.lock,后者存放将包的依赖关系,查看依赖关系是十分方便。
-
各个地方使用了哈希校验,无论安装还是卸载包都十分安全,且会自动公开安全漏洞。
-
通过加载.env文件简化开发工作流程。
-
支持Python2和 Python3,在各个平台的命令都是一样的。
-
查看是否已经安装pip
# 打开 cmd ,运行以下命令以确保系统中已安装 pip:
pip --version
- 安装
#pipenv 通过运行以下命令进行安装:
pip install pipenv
- 测试
# 安装成功后在 cmd 输入以下命令:
py -m site --user-site
# 会返回 pipenv.exe 所在文件夹。
# 如:C:\Users\admin\AppData\Roaming\Python\Python39\site-packages
- 创建
# 接下来,通过使用以下命令创建一个新环境,在指定目录下创建虚拟环境, 会使用本地默认版本的python
pipenv install
- 指定版本创建
pipenv --two # 使用当前系统中的Python2 创建环境
pipenv --three # 使用当前系统中的Python3 创建环境
pipenv --python 3 # 指定使用Python3创建环境
pipenv --python 3.6 # 指定使用Python3.6创建环境
pipenv --python 2.7.14 # 指定使用Python2.7.14创建环境
- 激活虚拟环境
pipenv shell
- 删除
pipenv --rm
- 退出
使用exit退出当前虚拟环境
conda
- 创建
- 删除
poetry
Pipenv 描绘了一个美梦,让我们以为 Python 也有了其他语言那样完善的包管理器,不过这一切却在后来者 Poetry 这里得到了更好的实现。
这几年 Pipenv 收获了很多用户,但是也暴露了很多问题。虽然 Lock 太慢、Windows 支持不好和 bug 太多的问题都已经改进了很多,但对我来说,仍然不能接受随时更新锁定依赖的设定,在上一篇文章《不要用 Pipenv》里也吐槽了很多相关的问题。
在这篇文章里,我会介绍一个看起来和事实上都更靠谱的 Python 虚拟环境和依赖管理工具 Poetry,作者是 Sébastien Eustace。这是一个新的坑吗?我想并不是,尽管这是一个更年轻的工具,1.0 还没有发布,也存在各种各样的 bug,但至少基本使用流程没有问题,用法设计也符合直觉。
Poetry 是什么
Poetry 和 Pipenv 类似,是一个 Python 虚拟环境和依赖管理工具,另外它还提供了包管理功能,比如打包和发布。你可以把它看做是 Pipenv 和 Flit 这些工具的超集。它可以让你用 Poetry 来同时管理 Python 库和 Python 程序。
主页:https://poetry.eustace.io/
源码:https://github.com/sdispater/poetry
文档:https://poetry.eustace.io/docs
- 安装
官方推荐的安装命令是使用自带的 get-poetry.py 脚本,使用 curl:
curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python
或者直接下载这个安装脚本 get-poetry.py,然后在本地执行。
因为这个命令在安装时会从 GitHub 下载一个 7M 的压缩包,如果不用代理某些地区可能会很慢。实际测试使用代理安装耗时约 30 秒,不用代理等了 5 分钟,然后连接被重置。
如果没有用代理,可以用 pip 安装(不过 Poetry 官方文档不建议这么做,因为有可能会造成依赖冲突,可以考虑用 pipx 或 pipsi):
pip install poetry
# pip install --user poetry
- 测试
poetry --version
Poetry 的基本用法
Poetry 的用法很简单,大部分命令和 Pipenv 接近。我们需要先了解一些基本概念和 Tips:
- 使用 PEP 518引入的新标准 pyproject.toml 文件管理依赖列表和项目的各种 meta 信息,用来替代
Pipfile、requirements.txt、setup.py、setup.cfg、MANIFEST.in 等等各种配置文件。 - 依赖分为两种,普通依赖(生产环境)和开发依赖。
- 安装某个包,会在 pyproject.toml 文件中默认使用 upper
bound(中文翻译?)版本限定,比如 Flask^1.1。这被叫做 Caret
requirements(中文翻译?),比如某个依赖的版本限定是 ^2.9.0,当你执行 poetry update
的时候,它或许会更新到 2.14.0,但不会更新到 3.0.0;假如固定的版本是 ^0.1.11,它可能会更新到
0.1.19,但不会更新到 0.2.0。总之,在更新依赖的时候不会修改最左边非零的数字号版本(对于 SemVer 版本号而言),这样的默认设定可以确保你在更新依赖的时候不会更新到具有不兼容变动的版本。另外也支持更多依赖版本限定符号。 - 不会像Pipenv 那样随时更新你的锁定依赖版本,锁定依赖存储在 poetry.lock 文件里(这个文件会自动生成)。所以,记得把你的poetry.lock 文件纳入版本控制。
- 执行 poetry 或 poetry list 命令查看所有可用的命令。
如果你想了解更多进阶的内容,比如设置命令行补全、打包和发布等等,请阅读 Poetry 文档。
准备工作
如果你是在一个已有的项目里使用 Poetry,你只需要执行 poetry init 命令来创建一个 pyproject.toml 文件:
poetry init
根据它的提示输入你的项目信息,不确定的内容就按下 Enter 使用默认值,后续也可以手动更新。指定依赖的环节可以跳过,手动安装会更高效一点。
如果你想创建一个新的 Python 项目,使用 poetry new <文件夹名称> 命令可以创建一个项目模板:
poetry new foo
这会创建一个这样的项目结构:
foo
├── pyproject.toml
├── README.rst
├── foo
│ └── __init__.py
└── tests
├── __init__.py
└── test_foo.py
如果你想使用 src 文件夹,可以添加 --src 选项,这会把程序包嵌套在 src 文件夹里。
创建虚拟环境
使用 poetry install 命令创建虚拟环境(确保当前目录有 pyproject.toml 文件):
poetry install
这个命令会读取 pyproject.toml 中的所有依赖(包括开发依赖)并安装,如果不想安装开发依赖,可以附加 --no-dev 选项。如果项目根目录有 poetry.lock 文件,会安装这个文件中列出的锁定版本的依赖。如果执行 add/remove 命令的时候没有检测到虚拟环境,也会为当前目录自动创建虚拟环境。
激活虚拟环境
执行 poetry 开头的命令并不需要激活虚拟环境,因为它会自动检测到当前虚拟环境。如果你想快速在当前目录对应的虚拟环境中执行命令,可以使用 poetry run <你的命令> 命令,比如:
poetry run python app.py
如果你想显式的激活虚拟环境,使用 poetry shell 命令:
poetry shell
安装包
使用 poetry add 命令来安装一个包:
poetry add flask
添加 --dev 参数可以指定为开发依赖:
poetry add pytest --dev
追踪 & 更新包
使用 poetry show 命令可以查看所有安装的依赖(可以传递包名称作为参数查看具体某个包的信息):
poetry show
添加 --tree 选项可以查看依赖关系:
poetry show --tree
添加 --outdated 可以查看可以更新的依赖:
poetry show --outdated
执行 poetry update 命令可以更新所有锁定版本的依赖:
poetry update
如果你想更新某个指定的依赖,传递包名作为参数:
poetry update foo
卸载包
使用 poetry remove <包名称> 卸载一个包:
poetry remove foo
常用配置
Poetry 的配置存储在单独的文件中,比 Pipenv 设置环境变量的方式要方便一点。配置通过 poetry config 命令设置,比如下面的命令可以写入 PyPI 的账号密码信息:
poetry config http-basic.pypi username password
下面的命令设置在项目内创建虚拟环境文件夹:
poetry config settings.virtualenvs.in-project true
另一个常用的配置是设置 PyPI 镜像源,以使用豆瓣提供的 PyPI 镜像源为例,你需要在 pyproject.toml 文件里加入这部分内容:
[[tool.poetry.source]]
name = "douban"
url = "https://pypi.doubanio.com/simple/"
不过经过测试 Poetry 会使用 pip.ini 设置的 PyPI 镜像,而且豆瓣的源好像很久没更新了(创建虚拟环境安装的默认依赖里 importlib-metadata==0.20 找不到),这篇文章列出了一些其他国内的 PyPI 源。
总结
总的来说,我愿意深入尝试和使用 Poetry。当然,经过使用 Pipenv 的痛苦经历,我对推荐工具这种事情变得更保守了。所以我不推荐 Python 初学者使用,不推荐直接在生产环境使用,不推荐没法正常访问国际互联网的人使用。
列一些我了解到的优缺点:
优点
- 使用标准的 pyproject.toml 文件,不用写多个配置文件
- 同时支持管理 Python 程序和 Python 库
- 更符合直觉的默认设计,比如不会随便更新锁定版本的依赖
- 干净简洁的命令行输出,没有星星和蛋糕
- 安装包的时候,使用 upper bound 版本限定,而不是 Pipenv 默认的通配符
- 卸载包的时候,直接卸载孤立的子依赖,不需要像 Pipenv 那样需要再执行 pipenv
clean
缺点
- 「poetry」这个单词有一点难打……
- 引入新的 pyproject.toml 标准,旧项目需要一点迁移成本和学习成本
- 会有一些潜在的bug
- 解析依赖的过程偶尔会久一点
- 对虚拟环境的管理控制有些弱,没有 Pipenv 那样的删除虚拟环境和清空依赖的操作
- 缺少一个稳定的维护团队,有大量 issue 和 PR 等待处理,但情况在逐渐好转
当然,你还是可以选择继续使用 virtualenv/venv 和 pip 这些基础工具,直到有一个完美的解决方案出现。或者,也可以选择试试新东西,然后尝试改进它,让完美的解决方案早一点出现。