使用pipenv管理你的项目

栏目: Python · 发布时间: 6年前

内容简介:使用pipenv管理你的项目

刚才使用pipenv发现了一个bug, 顺手提了个的PR。无聊之下翻了下贡献者列表,貌似没有一个我国的开发者!我的普及工作任重而道远啊,我写篇文章给大家介绍下这个终极大杀器。

Python开发者应该听过pip、easy_install和virtualenv,如果看过我的书应该还知道 virtualenvwrapper、virtualenv-burrito和autoenv,再加上pyvenv、venv(Python 3标准库)、pyenv…

额,是不是有种发懵的感觉?

那么现在有个好消息,你可以只使用终极方案: pipenv + autoenv(可选)。

「终极方案」,听起来好噱头呀。给出我的理由之前我们先了解一下 Python 虚拟环境和包管理的历史吧。

历史

在Python发展史上出现了很多创建和发布包的工具。 当你想要把你的项目分享出去,放到PYPI或者其他托管服务上的时候,就需要借助这样的 工具 来构建和分发项目。早在1998年Python标准库内置了模块distutils,但是只提供了有限的支持,之后社区选择通过setuptools这个包实现构建和发布,它自带easy_install,能帮助你找到、下载、安装以及更新需要使用的包。不过依然功能很有限,比如不能删除包。

当你做一个专职的Python开发,独立的虚拟环境也是一个开发中迫切需要的功能,在这里请大家记住一个 Ian Bicking(下称ianb) 的开发者,08年,他开发了virtualenv。

社区一些Python核心开发者和知名项目(如Django)核心开发者也在支持和推动这件事,后来成立了pypa(Python Packaging Authority),pypa早期做的就是pip - 现在最主流的安装包的工具。再提一下,ianb也是pip的早期核心开发者。

不过非常遗憾,由于和社区产生了一些矛盾,ianb很早之前就不再写Python项目(可见这矛盾多大呀 :open_mouth:),virtualenv也转给了其他开发者,这是Python社区一个极大的损失。

现在pip和virtualenv已经被大家所熟知,甚至可以说是Python官方的包管理和虚拟环境选择。不过其实还是有问题,我举几个例子:

  1. 必须手动安装或删除某些特定版本的包,并记得定期更新requirements.txt文件,以保持项目环境的一致
  2. 有时项目中需要有多个requirements.txt文件,比如开发时应该用dev-requirements.txt,现有的模式不能满足这些复杂的需要
  3. 卸载包的时候只是卸载包自己,不能处理相关依赖,时间久了项目环境就混乱了

pipenv 是什么?

Pipenv 是 Python 项目的依赖管理器。其实它不是什么先进的理念和技术,如果你熟悉 Node.js 的 npm/yarn 或 Ruby 的 bundler,那么就非常好理解了,它在思路上与这些工具类似。尽管pip可以安装Python包,但仍推荐使用Pipenv,因为它是一种更高级的工具,可简化依赖关系管理的常见使用情况。

主要特性包含:

  1. 根据 Pipfile 自动寻找项目根目录。
  2. 如果不存在,可以自动生成 Pipfile 和 Pipfile.lock。
  3. 自动在项目目录的 .venv 目录创建虚拟环境。(当然这个目录地址通过设置WORKON_HOME改变)
  4. 自动管理 Pipfile 新安装和删除的包。
  5. 自动更新 pip。

对于新手和老手来说都是更好的选择。

pipenv 都包含什么?

pipenv 是 Pipfile 主要倡导者、requests 作者 Kenneth Reitz 写的一个命令行工具,主要包含了Pipfile、pip、click、requests和virtualenv。Pipfile和pipenv本来都是Kenneth Reitz的个人项目,后来贡献给了pypa组织。Pipfile是社区拟定的依赖管理文件,用于替代过于简陋的 requirements.txt 文件。

Pipfile的基本理念是:

  1. Pipfile 文件是 TOML 格式而不是 requirements.txt 这样的纯文本。
  2. 一个项目对应一个 Pipfile,支持开发环境与正式环境区分。默认提供 default 和 development 区分。
  3. 提供版本锁支持,存为 Pipfile.lock。

click是Flask作者 Armin Ronacher 写的命令行库,现在Flask以及集成了。

接下来,我们看看怎么使用它吧

入门

pipenv兼容Python 2/3,我们这里以Mac下Python 3为例:

安装pipenv

❯ brew install python3  # 如果已经安装了可以忽略
❯ python3 -m pip install --upgrade --force-reinstall pip
❯ pip3 install pipenv --user  # 推荐安装在个人目录下
❯ export PATH="/Users/dongweiming/Library/Python/3.6/bin:$PATH"  # 把用户目录下bin放在最前面,这样可以直接使用pipenv了

使用pipenv

用一个空目录体验一下:

❯ mkdir test_pipenv
❯ cd test_pipenv
❯ pipenv install  # 创建一个虚拟环境
Creating a virtualenv for this project…
...
Installing setuptools, pip, wheel...done.

Virtualenv location: /Users/dongweiming/.virtualenvs/test_pipenv-GP_s2TW5
Creating a Pipfile for this project…
Pipfile.lock not found, creating…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (c23e27)!
Installing dependencies from Pipfile.lock (c23e27)…
  :snake:   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
To activate this project's virtualenv, run the following:
 $ pipenv shell

❯ which python3
/usr/local/Cellar/python3/3.6.1/bin/python3  # 还是mac自带的Python

❯ pipenv shell  # 激活虚拟环境
Spawning environment shell (/bin/zsh). Use 'exit' to leave.
source /Users/dongweiming/.virtualenvs/test_pipenv-GP_s2TW5/bin/activate

❯ which python3  # 已经在虚拟环境里了
/Users/dongweiming/.virtualenvs/test_pipenv-GP_s2TW5/bin/python3

❯ exit  # 退出虚拟环境

❯ which python3
/usr/local/Cellar/python3/3.6.1/bin/python3

以上就是原来virtualenv的基本用法了。我们看一下当前目录现在是什么样子的:

❯ ls
Pipfile  Pipfile.lock

这个环境下目前什么都没有。我们安装2个包:

❯ pipenv install elasticsearch-dsl requests
Installing elasticsearch-dsl…
...
Adding elasticsearch-dsl to Pipfile's [packages]…
Installing requests…
...
Adding requests to Pipfile's [packages]…
  PS: You have excellent taste! :sparkles: :cake: :sparkles:
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (8d307d)!

现在Pipfile.lock已经更新了,包含了 elasticsearch-dsl、requests 和相关依赖的包信息。

另外如果你添加–two或–three标志到上面的最后一个命令,它分别使用Python 2或3来初始化你的项目。 否则将使用默认版本的Python。

可以看一下依赖关系:

❯ pipenv graph
elasticsearch-dsl==6.1.0
  - elasticsearch [required: <7.0.0,>=6.0.0, installed: 6.1.1]
    - urllib3 [required: <1.23,>=1.21.1, installed: 1.22]
  - ipaddress [required: Any, installed: 1.0.19]
  - python-dateutil [required: Any, installed: 2.6.1]
    - six [required: >=1.5, installed: 1.10.0]
  - six [required: Any, installed: 1.10.0]
requests==2.18.4
  - certifi [required: >=2017.4.17, installed: 2017.11.5]
  - chardet [required: <3.1.0,>=3.0.2, installed: 3.0.4]
  - idna [required: <2.7,>=2.5, installed: 2.6]
  - urllib3 [required: <1.23,>=1.21.1, installed: 1.22]

可以看到,他俩都依赖了urllib3。虽然现在pipenv不能直接卸载包及其依赖,但是由于它提供了良好的接口,我们还是可以实现:

❯ pipenv uninstall `pipenv graph --json |python3 depends.py requests`
Un-installing certifi…
Uninstalling certifi-2017.11.5:
  Successfully uninstalled certifi-2017.11.5

No package certifi to remove from Pipfile.
Un-installing requests…
Uninstalling requests-2.18.4:
  Successfully uninstalled requests-2.18.4

Removing requests from Pipfile…
Un-installing idna…
Uninstalling idna-2.6:
  Successfully uninstalled idna-2.6

No package idna to remove from Pipfile.
Un-installing chardet…
Uninstalling chardet-3.0.4:
  Successfully uninstalled chardet-3.0.4

No package chardet to remove from Pipfile.
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (c05ac4)!

其中depends.py脚本会解析依赖关系,排除其他包依赖的项目然后删除:

❯ cat depends.py
import sys
import json

package = sys.argv[1]
other_dependencies = set()
removing_dependencies = set([package])

for i in json.load(sys.stdin):
    for p in i['dependencies']:
        key = p['key']
        if i['package']['key'] == package:
            removing_dependencies.add(key)
        else:
            other_dependencies.add(key)

print(' '.join(removing_dependencies - other_dependencies))

再看一下现在环境中的包依赖关系:

❯ pipenv graph
elasticsearch-dsl==6.1.0
  - elasticsearch [required: >=6.0.0,<7.0.0, installed: 6.1.1]
    - urllib3 [required: >=1.21.1,<1.23, installed: 1.22]
  - ipaddress [required: Any, installed: 1.0.19]
  - python-dateutil [required: Any, installed: 2.6.1]
    - six [required: >=1.5, installed: 1.10.0]
  - six [required: Any, installed: 1.10.0]

是不是很干净呢?

其他功能

除了上述基本功能以外,pipenv还有很多附加的功能,我举几个日常比较常用的例子:

❯ pipenv run which python # 「pipenv run」可以激活虚拟环境,并使用 shell 命令
/Users/dongweiming/.virtualenvs/test_pipenv-GP_s2TW5/bin/python
❯ pipenv check  # 检查装的包的安全性
Checking PEP 508 requirements…
Passed!
Checking installed package safety…
All good!
❯ pipenv --man  # 传统的看文档的方法
❯ pipenv check --style depends.py  # 代码Flake8检查,在这里我修改了depends.py让它故意有问题
/Users/dongweiming/test_pipenv/depends.py:1:1: F401 'os' imported but unused

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

结构化计算机组成

结构化计算机组成

Andrew S.Tanenbaum / 刘卫东 / 机械工业出版社 / 2001-10-1 / 46.00

AndrewcS.Tanenbaum获得过美国麻省理工学院的理学学士学位和加利福尼亚大学伯克利分校的哲学博士学位,目前是荷兰阿姆斯特丹Vrije大学计算机科学系的教授,并领导着一个计算机系统的研究小组.同时,他还是一所计算与图像处理学院的院长,这是由几所大学合作成立的研究生院.尽管社会工作很多,但他并没有中断学术研究. 多年来,他在编译技术.操作系统.网络及局域分布式系统方面进行了大量的一起来看看 《结构化计算机组成》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具