跳转至

pipenv

鸡汤: 别灰心,人生就是这样起起落落落落落落落落落落落的。

1. 介绍

github 地址 pipenv github

  pipenv 是Kenneth Reitz大神的作品,能够有效管理Python多个环境,各种包。过去我们一般用virtualenv搭建虚拟环境,管理python版本,但是跨平台的使用不太一致,且有时候处理包之间的依赖总存在问题;过去也常常用pip进行包的管理,pip已经足够好,但是仍然推荐pipenv,相当于virtualenv和pip的合体,且更加强大.

  pipenv主要有以下特性:

  • 1.pipenv集成了pip,virtualenv两者的功能,且完善了两者的一些缺陷。
  • 2.过去用virtualenv管理requirements.txt文件可能会有问题,Pipenv使用Pipfile和Pipfile.lock,后者存放将包的依赖关系,查看依赖关系是十分方便。
  • 3.各个地方使用了哈希校验,无论安装还是卸载包都十分安全,且会自动公开安全漏洞。。
  • 4.通过加载.env文件简化开发工作流程。
  • 5.支持Python2 和 Python3,在各个平台的命令都是一样的。

2. 安装

2.1 安装pipenv

  首先确保安装了python3和对应的pip3,如果python和pip对应的是python3.x,忽略数字3。

pip3 install pipenv

2.2 创建环境

cd /tmp/
mkdir pipenv_workflow
cd pipenv_workflow/
pipenv install

详细操作

root@leco:~# cd /tmp/
root@leco:/tmp# mkdir pipenv_workflow
root@leco:/tmp# cd pipenv_workflow/
root@leco:/tmp/pipenv_workflow# pipenv install
Creating a virtualenv for this project…
Pipfile: /tmp/pipenv_workflow/Pipfile
Using /usr/bin/python (3.5.2) to create virtualenv…
⠋ Creating virtual environment...Already using interpreter /usr/bin/python
Using base prefix '/usr'
New python executable in /root/.local/share/virtualenvs/pipenv_workflow-ZrYDvzQ1/bin/python
Installing setuptools, pip, wheel...
done.
✔ Successfully created virtual environment! 
Virtualenv location: /root/.local/share/virtualenvs/pipenv_workflow-ZrYDvzQ1
Creating a Pipfile for this project…
Pipfile.lock not found, creating…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (a79791)!
Installing dependencies from Pipfile.lock (a79791)…
     ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
root@leco:/tmp/pipenv_workflow# ls
Pipfile  Pipfile.lock
notice
初始化好虚拟环境后,会在项目目录下生成2个文件Pipfile和Pipfile.lock。为pipenv包的配置文件,代替原来的 requirement.txt。

项目提交时,可将Pipfile 文件和Pipfile.lock文件一并提交,待其他开发克隆下载,根据此Pipfile 运行命令pipenv install --dev生成自己的虚拟环境。

Pipfile.lock 文件是通过hash算法将包的名称和版本,及依赖关系生成哈希值,可以保证包的完整性。
Pipfile 存放着当前虚拟环境的配置信息,包含python版本,pypi源,以及项目安装的依赖库。
    pipenv根据这个来寻找项目的根目录。
    Pipfile 文件是 TOML 格式而不是 requirements.txt 那样的纯文本。
    一个项目对应一个 Pipfile,支持开发环境与正式环境区分。默认提供 default 和 development 区分
    Pipfile.lock 顾名思义,这个文件时对于Pipfile的一个锁定。支持锁定项目不同的版本所依赖的环境.

2.3 安装包

cat>main.py<<EOF
#/usr/bin/env python
# author: caimengzhi
# date  : 2019-09-05 15:58
# detail: get you local wan network ip

import requests
response = requests.get('https://httpbin.org/ip')
print('Your IP is {0}'.format(response.json()['origin']))
EOF
详细操作
root@leco:/tmp/pipenv_workflow# cat>main.py<<EOF
> #/usr/bin/env python
> # author: caimengzhi
> # date  : 2019-09-05 15:58
> # detail: get you local wan network ip
> 
> import requests
> response = requests.get('https://httpbin.org/ip')
> print('Your IP is {0}'.format(response.json()['origin']))
> EOF

# 使用pipenv管理的环境来运行
root@leco:/tmp/pipenv_workflow# pipenv run python main.py 
Your IP is 114.221.22.42, 114.221.22.42

到目前为止,pipenv简单流程已经完毕。

3. 基本命令

pip install --user --upgrade pipenv   # 用户安装pipenv
pipenv --three       # 会使用当前系统的Python3创建环境
pipenv --two         # 使用python2创建
pipenv --python 3.6  # 指定某一Python版本创建环境
pipenv run python    # 文件名
pipenv run pip ...   # 运行pip
pipenv shell         # 激活虚拟环境
pipenv --where       # 显示目录信息
pipenv --venv        # 显示虚拟环境信息
pipenv --py          # 显示Python解释器信息
pipenv install requests # 安装相关模块并加入到Pipfile
pipenv install django==1.11 # 安装固定版本模块并加入到Pipfile
pipenv graph    # 显示依赖图
pipenv check    # 检查安全漏洞
pipenv uninstall requests   # 卸载包并从Pipfile中移除
pipenv uninstall --all      # 卸载全部包

3.1 快速创建并进入虚拟环境

  前提条件: 系统已安装python2和python3

# 创建python3环境
pipenv --three

# 创建python2环境
pipenv --two

# 在上一步新建环境的目录下,运行此命令才有效
pipenv shell

详细操作
root@leco:/tmp# mkdir env_pip
root@leco:/tmp# cd env_pip/
root@leco:/tmp/env_pip# mkdir test1
root@leco:/tmp/env_pip# mkdir test2
root@leco:/tmp/env_pip/test1# pipenv --three
Creating a virtualenv for this project…
Pipfile: /tmp/env_pip/test1/Pipfile
Using /usr/bin/python (3.5.2) to create virtualenv…
⠏ Creating virtual environment...Already using interpreter /usr/bin/python
Using base prefix '/usr'
New python executable in /root/.local/share/virtualenvs/test1-Rm0e6V0t/bin/python
Installing setuptools, pip, wheel...
done.
✔ Successfully created virtual environment! 
Virtualenv location: /root/.local/share/virtualenvs/test1-Rm0e6V0t
Creating a Pipfile for this project…
root@leco:/tmp/env_pip/test1# ls
Pipfile


root@leco:/tmp/env_pip/test1# cd ..
root@leco:/tmp/env_pip# cd test2/
root@leco:/tmp/env_pip/test2# pipenv --two
Creating a virtualenv for this project…
Pipfile: /tmp/env_pip/test2/Pipfile
Using /usr/bin/python2 (2.7.12) to create virtualenv…
⠙ Creating virtual environment...New python executable in /root/.local/share/virtualenvs/test2-qIkZ0KBA/bin/python2
Also creating executable in /root/.local/share/virtualenvs/test2-qIkZ0KBA/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /usr/bin/python2
✔ Successfully created virtual environment! 
Virtualenv location: /root/.local/share/virtualenvs/test2-qIkZ0KBA
Creating a Pipfile for this project…
root@leco:/tmp/env_pip/test2# ls
Pipfile

进入虚拟环境
root@leco:/tmp/env_pip/test2# pipenv shell
Launching subshell in virtual environment…
root@leco:/tmp/env_pip/test2#  . /root/.local/share/virtualenvs/test2-qIkZ0KBA/bin/activate
(test2) root@leco:/tmp/env_pip/test2# 
注意
小技巧: 
如果子级目录的父级目录已经创建过虚拟环境, 则子级目录无法创建虚拟目录(子级目录无法生成Pipfile, 
子级默认会使用父级的虚拟环境), 如果确实需要在子级目录创建独立的虚拟环境,可以运行 pipenv --where 
获取父级虚拟环境的名字, 根据虚拟环境的前半部分名字, 确定父级目录的位置, 然后删除父级目录下的 Pipfile , 
Pipfile.lock , 运行 exit 退出父级虚拟环境,然后回到子目录,运行 pipenv --three 创建子目录的虚拟环境即可

3.2 查看安装的包

详细操作

root@leco:/tmp/env_pip/test1# pipenv graph
gmail==0.6.3
requests==2.22.0
  - certifi [required: >=2017.4.17, installed: 2019.6.16]
  - chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
  - idna [required: >=2.5,<2.9, installed: 2.8]
  - urllib3 [required: >=1.21.1,<1.26,!=1.25.1,!=1.25.0, installed: 1.25.3]

或者进入查看
root@leco:/tmp/env_pip/test1# pipenv shell
Launching subshell in virtual environment…
root@leco:/tmp/env_pip/test1#  . /root/.local/share/virtualenvs/test1-Rm0e6V0t/bin/activate
(test1) root@leco:/tmp/env_pip/test1# pip list
Package    Version  
---------- ---------
certifi    2019.6.16
chardet    3.0.4    
gmail      0.6.3    
idna       2.8      
pip        19.2.3   
requests   2.22.0   
setuptools 41.2.0   
urllib3    1.25.3   
wheel      0.33.6   

3.3 安装/卸载软件

  • 进入安装

详细操作

(test1) root@leco:/tmp/env_pip/test1# ls
Pipfile
(test1) root@leco:/tmp/env_pip/test1# pipenv shell
Shell for /root/.local/share/virtualenvs/test1-Rm0e6V0t already activated.
No action taken to avoid nested environments.
(test1) root@leco:/tmp/env_pip/test1# pip list
Package    Version
---------- -------
pip        19.2.3 
setuptools 41.2.0 
wheel      0.33.6 
(test1) root@leco:/tmp/env_pip/test1# pip install gmail
Collecting gmail
  Downloading https://files.pythonhosted.org/packages/7a/ea/a22dde9957672e37bc45b1b9a0788e7388923a7a938adfeac089259819e1/gmail-0.6.3.tar.gz
Building wheels for collected packages: gmail
  Building wheel for gmail (setup.py) ... done
  Created wheel for gmail: filename=gmail-0.6.3-cp35-none-any.whl size=10748 sha256=94346fa5b90a6de4217e76fc4393bf5baf5fd328f04efa70fad2485cb0d671e0
  Stored in directory: /root/.cache/pip/wheels/66/0f/ea/f1061d7fe2a8b3242dc0bc21e54ab794da92431233002ef783
Successfully built gmail
Installing collected packages: gmail
Successfully installed gmail-0.6.3
(test1) root@leco:/tmp/env_pip/test1# pip list
Package    Version
---------- -------
gmail      0.6.3  
pip        19.2.3 
setuptools 41.2.0 
wheel      0.33.6 
  • 直接安装

详细操作

root@leco:/tmp/env_pip/test1# pipenv install requests
Installing requests…
✔ Installation Succeeded 
Pipfile.lock not found, creating…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
✔ Success! 
Updated Pipfile.lock (0b4483)!
Installing dependencies from Pipfile.lock (0b4483)…
     ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 5/5 — 0

查看安装的包
root@leco:/tmp/env_pip/test1# pipenv graph
gmail==0.6.3
requests==2.22.0
  - certifi [required: >=2017.4.17, installed: 2019.6.16]
  - chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
  - idna [required: >=2.5,<2.9, installed: 2.8]
  - urllib3 [required: >=1.21.1,<1.26,!=1.25.1,!=1.25.0, installed: 1.25.3]
  • 卸载
root@leco:/tmp/dic_pipenv# pipenv graph
requests==2.22.0
  - certifi [required: >=2017.4.17, installed: 2019.6.16]
  - chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
  - idna [required: >=2.5,<2.9, installed: 2.8]
  - urllib3 [required: >=1.21.1,<1.26,!=1.25.1,!=1.25.0, installed: 1.25.3]
yagmail==0.11.220

root@leco:/tmp/dic_pipenv# 
root@leco:/tmp/dic_pipenv# pipenv uninstall yagmail
Uninstalling yagmail…
Uninstalling yagmail-0.11.220:
  Successfully uninstalled yagmail-0.11.220

后者进入虚拟环境中再去卸载
root@leco:/tmp/env_pip/test1# pipenv shell
Launching subshell in virtual environment…
root@leco:/tmp/env_pip/test1#  . /root/.local/share/virtualenvs/test1-Rm0e6V0t/bin/activate
(test1) root@leco:/tmp/env_pip/test1# pip list
Package    Version  
---------- ---------
certifi    2019.6.16
chardet    3.0.4    
gmail      0.6.3    
idna       2.8      
pip        19.2.3   
setuptools 41.2.0   
urllib3    1.25.3   
wheel      0.33.6   
(test1) root@leco:/tmp/env_pip/test1# pip uninstall gmail
Uninstalling gmail-0.6.3:
  Would remove:
    /root/.local/share/virtualenvs/test1-Rm0e6V0t/lib/python3.5/site-packages/gmail-0.6.3.dist-info/*
    /root/.local/share/virtualenvs/test1-Rm0e6V0t/lib/python3.5/site-packages/gmail/*
Proceed (y/n)? y
  Successfully uninstalled gmail-0.6.3
(test1) root@leco:/tmp/env_pip/test1# pip list
Package    Version  
---------- ---------
certifi    2019.6.16
chardet    3.0.4    
idna       2.8      
pip        19.2.3   
setuptools 41.2.0   
urllib3    1.25.3   
wheel      0.33.6   

3.4 退出虚拟环境

(test1) root@leco:/tmp/env_pip/test1# exit
exit

3.5 检查安全漏洞

root@leco:/tmp/env_pip/test1# pipenv check
Checking PEP 508 requirements…
Passed!
Checking installed package safety…
All good!

3.6 扩展命令

  • 查看虚拟环境python解释器所在位置
root@leco:/tmp/env_pip/test1# pipenv --py
/root/.local/share/virtualenvs/test1-Rm0e6V0t/bin/python
  • 查看虚拟环境所在位置
root@leco:/tmp/env_pip/test1# pipenv --venv
/root/.local/share/virtualenvs/test1-Rm0e6V0t
  • 使用更底层的命令 pip freeze
root@leco:/tmp/env_pip/test1# pipenv run pip freeze
certifi==2019.6.16
chardet==3.0.4
idna==2.8
urllib3==1.25.3
  • 只在安装开发阶段使用的软件包(和npm类似)

  • 安装Pipfile.lock的所有包(完整移植开发环境)

root@leco:/tmp/env_pip/test1# pipenv sync
Installing dependencies from Pipfile.lock (0b4483)…
     ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 5/5 — 00:00:10
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run

3.7 删除虚拟环境

root@leco:/tmp/env_pip/test1# pipenv --rm
Removing virtualenv (/root/.local/share/virtualenvs/test1-Rm0e6V0t)…
root@leco:/tmp/env_pip/test1# ls
Pipfile  Pipfile.lock
root@leco:/tmp/env_pip/test1# pipenv graph
Warning: No virtualenv has been created for this project yet! Consider running `pipenv install` first to automatically generate one for you or see`pipenv install --help` fo
r further instructions.

3.8 速度源

在使用pipenv的时候,常常会在安装的时候,一直卡在了 Locking 这里,通过加上 -v 参数,可以看到安装过程中的步骤信息,卡在了下载那里,这时应该可以意识到是因为网络的原因,pipenv创建的 Pipfile 中默认的pypi源是python官方的 https://pypi.python.org/simple 我们国内用户访问下载的时候会很慢。

所以,我一般会在创建好Pipfile以后,修改到文件中 source 块下的 url 字段,设置为国内的 pypi 源就好了,我推荐的是清华的pypi源,具体设置如下:

[[source]]

 url = "https://pypi.tuna.tsinghua.edu.cn/simple"
 verify_ssl = true
 name = "pypi"

3.9 管理依赖

Pipfile 包含关于项目的依赖包的信息,并取代通常在Python项目中使用的 requirements.txt 文件。 如果你之前的项目中存在requirements.txt文件,pipenv 可以很轻松的安装 requirements.txt 中的依赖包。

pipenv install -r requirements.txt
or
pipenv install --requirements requirements.txt

可以通过更新 Pipfile.lock 来冻结软件包名称及其版本以及其自己的依赖关系的列表。 这时需要使用lock关键字来完成,

pipenv lock

如果我们想要在虚拟环境中安装某个指定的库,比如 requests, 直接在 install 后面跟上就可以了:

pipenv install requests

如果想查看当前环境中第三方包之间的依赖关系,可以通过 pipenv graph 来查看:

root@leco:/tmp/dic_pipenv# pipenv graph
requests==2.22.0
  - certifi [required: >=2017.4.17, installed: 2019.6.16]
  - chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
  - idna [required: >=2.5,<2.9, installed: 2.8]
  - urllib3 [required: >=1.21.1,<1.26,!=1.25.1,!=1.25.0, installed: 1.25.3]
从输出可以看出,我们按照的 requests包,依赖于其他的四个包,pipenv 帮你自动管理着这些包这件的依赖关系、。我们可以看到 requests 依赖于 urllib3, 假设我们再安装一个包,并且这个包也同样依赖着 urllib3 ,当我们要卸载掉 requests 的时候,pipenv会自动检测这些包之间的依赖关系,因为 urllib3 依旧有其他包依赖,所以会保留,只会卸载掉其他的依赖库。(卸载的指令是pipenv uninstall

3.10 autoenv

安装好 autoenv 以后,autoenv 可以在进入项目之后自动检测项目目录的 .env文件激活项目所需的虚拟环境,这样能够保证每次切换不同项目的时候,都能自动进入相应项目所依赖的虚拟环境。

要实现 autoenv 自动识别项目目录中的 .env 文件,需要将 autoenv 的激活脚本添加到终端的 profile 中:

git clone git://github.com/kennethreitz/autoenv.git ~/.autoenv
echo 'source ~/.autoenv/activate.sh' >> ~/.bashrc
source ~/.bashrc
echo 'pipenv shell'>.env

详细操作

root@leco:/tmp/dic_pipenv# git clone git://github.com/kennethreitz/autoenv.git ~/.autoenv
root@leco:/tmp/dic_pipenv# echo 'source ~/.autoenv/activate.sh' >> ~/.bashrc
root@leco:/tmp/dic_pipenv# source /etc/profile

到工程下创建.env文件
root@leco:/tmp/dic_pipenv# pwd
/tmp/dic_pipenv
(dic_pipenv) root@leco:/tmp/dic_pipenv# echo 'pipenv shell'>.env

此时进入到工程下,会自动加载环境
root@leco:/tmp# cd dic_pipenv
Loading .env environment variables…
Launching subshell in virtual environment…
 . /root/.local/share/virtualenvs/dic_pipenv-8UTwMErR/bin/activate
Shell for UNKNOWN_VIRTUAL_ENVIRONMENT already activated.
No action taken to avoid nested environments.
root@leco:/tmp/dic_pipenv#  . /root/.local/share/virtualenvs/dic_pipenv-8UTwMErR/bin/activate

venv/bin/activate 代表python的虚拟环境位置,project表示你的项目文件夹,需要手动修改 pipenv借鉴了npm管理包的方式, 与virtualenv和virtualenvwrapper相比, pipenv对要更友好一些,推荐学习