Pipenv
的主页Pipenv
?pipenv
是 Pipfile
主要倡导者、requests
作者 Kenneth Reitz
写的一个命令行工具,主要包含了Pipfile
、pip
、click
、requests
和virtualenv
。Pipfile
和pipenv
本来都是Kenneth Reitz
的个人项目,后来贡献给了pypa
组织。Pipfile
是社区拟定的依赖管理文件,用于替代过于简陋的 requirements.txt
文件。Python
有哪些包和版本管理工具?pip
、virtualenv
、pyenv
Pipenv
的区别以及它类似与其他语言中的哪些工具?pip
只是一个Python
包管理的工具,也就是说它不能同时去管理项目的版本,举例来说,virtualenv
virtualenv
是一个创建隔绝的Python
环境的工具。virtualenv
创建一个包含所有必要的可执行文件的文件夹,用来使用Python
工程所需的包。它的原理其实很简单,就是在创建完新的虚拟环境之后,在激活环境的同时,在环境变量里面加上了指定虚拟环境的Python
路径而已virtualenv
这么好用了,为什么官方更推荐使用Pipenv
呢,因为它在virtualenv
之上又封装了一层,这就好像requests
在urllib
等网络库之后又封装了一层,更加人性化,以及更加丰富的、简洁的语法自然是更受欢迎,而且更加独特的是其在对于依赖的处理更加细节化,当下载一个新的包时,会自动对包加锁处理,检查其依赖包的包装情况。Pipenv
也是借鉴于Node
的NPM
,Ruby
的GEM
等等,大家感兴趣可以去看看他们的原理,我们会在之后的文章中来摸索一下他们的设计原理。2.具体使用
##安装
Pipenv 是基于 Python 开发的包,所以可以直接用 pip 来安装,命令如下:
pip3 install pipenv
另外还有多种安装方式,如 Pipsi、Nix、Homebrew,安装方式可以参考:http://pipenv.readthedocs.io/en/latest/#install-pipenv-today
##基本使用
首先我们可以新建一个项目,例如叫做 PipenvTest,然后新建一个 Python 脚本,例如叫 main.py,内容为:
import django
print(django.get_version())
直接用系统的 Python3 运行此脚本:
python3 main.py
结果如下:
1.11
我们可以看到系统安装的 Django 版本是 1.11。但是我们想要本项目基于 Django 2.x 开发,当然我们可以选择将系统的 Django 版本升级,但这样又可能会影响其他的项目的运行,所以这并不是一个好的选择。为了不影响系统环境的 Django 版本,所以我们可以用 Pipenv 来创建一个虚拟环境。
在该目录下,输入 pipenv 命令即可查看命令的完整用法:
Usage: pipenv [OPTIONS] COMMAND [ARGS]...
Options:
--update Update Pipenv & pip to latest.
--where Output project home information.
--venv Output virtualenv information.
--py Output Python interpreter information.
--envs Output Environment Variable options.
--rm Remove the virtualenv.
--bare Minimal output.
--completion Output completion (to be eval'd).
--man Display manpage.
--three / --two Use Python 3/2 when creating virtualenv.
--python TEXT Specify which version of Python virtualenv should use.
--site-packages Enable site-packages for the virtualenv.
--jumbotron An easter egg, effectively.
--version Show the version and exit.
-h, --help Show this message and exit.
Usage Examples:
Create a new project using Python 3.6, specifically:
$ pipenv --python 3.6
Install all dependencies for a project (including dev):
$ pipenv install --dev
Create a lockfile containing pre-releases:
$ pipenv lock --pre
Show a graph of your installed dependencies:
$ pipenv graph
Check your installed dependencies for security vulnerabilities:
$ pipenv check
Install a local setup.py into your virtual environment/Pipfile:
$ pipenv install -e .
Commands:
check Checks for security vulnerabilities and against PEP 508 markers
provided in Pipfile.
graph Displays currently–installed dependency graph information.
install Installs provided packages and adds them to Pipfile, or (if none
is given), installs all packages.
lock Generates Pipfile.lock.
open View a given module in your editor.
run Spawns a command installed into the virtualenv.
shell Spawns a shell within the virtualenv.
uninstall Un-installs a provided package and removes it from Pipfile.
update Uninstalls all packages, and re-installs package(s) in [packages]
to latest compatible versions.
接下来我们首先验证一下当前的项目是没有创建虚拟环境的,调用如下命令:
pipenv --venv
结果如下:
No virtualenv has been created for this project yet!
这说明当前的项目尚未创建虚拟环境,接下来我们利用 Pipenv 来创建一个虚拟环境:
pipenv --python 3.6
执行完毕之后,样例输出如下:
Warning: the environment variable LANG is not set!
We recommend setting this in ~/.profile (or equivalent) for proper expected behavior.
Creating a virtualenv for this project…
Using /usr/local/bin/python3 to create virtualenv…
⠋Running virtualenv with interpreter /usr/local/bin/python3
Using base prefix '/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6'
New python executable in /Users/CQC/.local/share/virtualenvs/PipenvTest-VSTVh89E/bin/python3.6
Also creating executable in /Users/CQC/.local/share/virtualenvs/PipenvTest-VSTVh89E/bin/python
Installing setuptools, pip, wheel...done.
Virtualenv location: /Users/CQC/.local/share/virtualenvs/PipenvTest-VSTVh89E
这里显示 Pipenv 利用 /usr/local/bin/python3 作为 virtualenv 的解释器,然后在 /Users/CQC/.local/share/virtualenvs/PipenvTest-VSTVh89E/bin 目录下创建了一个新的 Python3 解释器,同时还创建了两个可执行文件别名 python3.6 和 python,另外我们还可以发现目录下多了一个 Pipfile 文件,这时虚拟环境就创建完成了。
我们切换到 PipenvTest-VSTVh89E/bin 目录查看一下文件结构,可以看到这里面包含了 pip、pip3、pip3.6、python、python3、python3.6 等可执行文件,实际上目录结构和使用 virtualenv 时是完全一样的,只不过文件夹的位置不同而已。
接下来我们可以切换到该虚拟环境下执行命令,执行如下命令即可:
pipenv shell
类似于source activate XXX
执行完毕之后样例输出如下:
Spawning environment shell (/bin/zsh). Use 'exit' to leave.
source /Users/CQC/.local/share/virtualenvs/PipenvTest-VSTVh89E/bin/activate
CQC-MAC% source /Users/CQC/.local/share/virtualenvs/PipenvTest-VSTVh89E/bin/activate
(PipenvTest-VSTVh89E) CQC-MAC%
实际上这也和 virtualenv 激活的流程一样,也是调用了类似 source venv/bin/activate 方法将这个路径加到全局环境变量最前面,这样就会优先调用该路径下的 python、python3、python3.6 可执行文件了。
这时候我们会发现命令行的样子就变了,前面多了一个 (PipenvTest-VSTVh89E) 的标识,代表当前我们已经切换到了虚拟环境下。
这时我们用 which 或 where 命令查看一下 Python 可执行文件的路径,命令如下:
(PipenvTest-VSTVh89E) CQC-MAC% which python3
/Users/CQC/.local/share/virtualenvs/PipenvTest-VSTVh89E/bin/python3
(PipenvTest-VSTVh89E) CQC-MAC% which python3.6
/Users/CQC/.local/share/virtualenvs/PipenvTest-VSTVh89E/bin/python3.6
(PipenvTest-VSTVh89E) CQC-MAC% which python
/Users/CQC/.local/share/virtualenvs/PipenvTest-VSTVh89E/bin/python
可以发现当前的 Python 可执行路径都被切换到了 PipenvTest-VSTVh89E/bin 目录下,调用的是虚拟环境中的 Python 解释器,这时我们重新执行刚才的脚本,命令如下:
(PipenvTest-VSTVh89E) CQC-MAC% python3 main.py
这时我们可以发现报了如下错误:
Traceback (most recent call last):
File "main.py", line 1, in
import django
ModuleNotFoundError: No module named 'django'
这其实是因为新的虚拟环境没有安装任何的 Python 第三方包,实际上如果直接使用 virtualenv 时也是这样的结果。这是因为新的虚拟环境是一个全新的 Python 环境,它默认只包含了 Python 内置的包以及 pip、wheel、setuptools 包,其他的第三方包都没有安装。
这时我们可以使用 Pipenv 来安装 django 包,命令如下:
pipenv install django
运行结果如下所示
Installing django…
Collecting django
Downloading Django-2.0.2-py3-none-any.whl (7.1MB)
Collecting pytz (from django)
Downloading pytz-2018.3-py2.py3-none-any.whl (509kB)
Installing collected packages: pytz, django
Successfully installed django-2.0.2 pytz-2018.3
Adding django to Pipfile's [packages]…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (e101fb)!
如果有这样的输出结果就代表成功安装了 Django
,可以看到此时安装的 Django
版本为 2.0,代表我们的虚拟环境成功安装了 Django
2.0 版本。
同时我们还注意到它输出了一句话叫做 Updated Pipfile.lock
,这时我们可以发现项目路径下又生成了一个 Pipfile.lock
文件,内容如下:
{
"_meta": {
"hash": {
"sha256": "7b9623243d9c22b1f333ee710aff70d0cbcdf1dd7e0aac69230dc76855d27270"
},
"host-environment-markers": {
"implementation_name": "cpython",
"implementation_version": "3.6.1",
"os_name": "posix",
"platform_machine": "x86_64",
"platform_python_implementation": "CPython",
"platform_release": "17.4.0",
"platform_system": "Darwin",
"platform_version": "Darwin Kernel Version 17.4.0: Sun Dec 17 09:19:54 PST 2017; root:xnu-4570.41.2~1/RELEASE_X86_64",
"python_full_version": "3.6.1",
"python_version": "3.6",
"sys_platform": "darwin"
},
"pipfile-spec": 6,
"requires": {},
"sources": [
{
"name": "pypi",
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
]
},
"default": {
"django": {
"hashes": [
"sha256:af18618ce3291be5092893d8522fe3919661bf3a1fb60e3858ae74865a4f07c2",
"sha256:9614851d4a7ff8cbd32b73c6076441f377c45a5bbff7e771798fb02c43c31f47"
],
"version": "==2.0.2"
},
"pytz": {
"hashes": [
"sha256:ed6509d9af298b7995d69a440e2822288f2eca1681b8cce37673dbb10091e5fe",
"sha256:f93ddcdd6342f94cea379c73cddb5724e0d6d0a1c91c9bdef364dc0368ba4fda",
"sha256:61242a9abc626379574a166dc0e96a66cd7c3b27fc10868003fa210be4bff1c9",
"sha256:ba18e6a243b3625513d85239b3e49055a2f0318466e0b8a92b8fb8ca7ccdf55f",
"sha256:07edfc3d4d2705a20a6e99d97f0c4b61c800b8232dc1c04d87e8554f130148dd",
"sha256:3a47ff71597f821cd84a162e71593004286e5be07a340fd462f0d33a760782b5",
"sha256:5bd55c744e6feaa4d599a6cbd8228b4f8f9ba96de2c38d56f08e534b3c9edf0d",
"sha256:887ab5e5b32e4d0c86efddd3d055c1f363cbaa583beb8da5e22d2fa2f64d51ef",
"sha256:410bcd1d6409026fbaa65d9ed33bf6dd8b1e94a499e32168acfc7b332e4095c0"
],
"version": "==2018.3"
}
},
"develop": {}
}
可以看到里面标识了 Python 环境基本信息,以及依赖包的版本及 hashes 值。
另外我们还可以注意到 Pipfile 文件内容也有更新,[packages] 部分多了一句 django = “*”,标识了本项目依赖于 Django,这个其实类似于 requirements.txt 文件。
那么到这里有小伙伴可能就会问了, Pipfile 和 Pipfile.lock 有什么用呢?
Pipfile 其实一个 TOML 格式的文件,标识了该项目依赖包的基本信息,还区分了生产环境和开发环境的包标识,作用上类似 requirements.txt 文件,但是功能更为强大。Pipfile.lock 详细标识了该项目的安装的包的精确版本信息、最新可用版本信息和当前库文件的 hash 值,顾明思义,它起了版本锁的作用,可以注意到当前 Pipfile.lock 文件中的 Django 版本标识为 ==2.0.2,意思是当前我们开发时使用的就是 2.0.2 版本,它可以起到版本锁定的功能。
举个例子,刚才我们安装了 Django 2.0.2 的版本,即目前(2018.2.27)的最新版本。但可能 Django 以后还会有更新,比如某一天 Django 更新到了 2.1 版本,这时如果我们想要重新部署本项目到另一台机器上,假如此时不存在 Pipfile.lock 文件,只存在 Pipfile文件,由于 Pipfile 文件中标识的 Django 依赖为 django = “*”,即没有版本限制,它会默认安装最新版本的 Django,即 2.1,但由于 Pipfile.lock 文件的存在,它会根据 Pipfile.lock 来安装,还是会安装 Django 2.0.2,这样就会避免一些库版本更新导致不兼容的问题。
请记住:任何情况下都不要手动修改 Pipfile.lock 文件!
好,接下来我们再回归正题,现在已经安装好了 Django 了,那么我们重新运行此脚本便可以成功输出 Django 版本信息了:
(PipenvTest-VSTVh89E) CQC-MAC% python3 main.py
结果如下:
2.0.2
这样我们就成功安装了 Django 2.x 了,和系统的 Django 1.11 没有任何冲突。
在此模式的命令行下,我们就可以使用虚拟环境下的 Python 解释器,而且所安装的依赖包对外部系统没有任何影响,而且使用 Pipfile 和 Pipfile.lock 来管理项目的依赖更加方便和健壮。
如果想要退出虚拟环境,只需要输入 exit 命令即可:
(PipenvTest-VSTVh89E) CQC-MAC% exit
➜ PipenvTest python3 main.py
1.11
输入退出命令之后,我们重新再运行此脚本,就会重新使用系统的 Python 解释器,Django 版本又重新回到了 1.11。
由此可以看来,有了 Pipenv,我们可以使用 Pipfile 和 Pipfile.lock 来方便地管理和维护项目的依赖包,而且可以实现虚拟环境运行,避免了包冲突问题,可谓一举两得。具体事例使用就是这样啦,大家还有什么不懂的可以看官方的文档,在文章最上方。
3.总结
嗯,是时候抛弃 virtualenv 和 pip 了!