[232]requests库作者另一神器Pipenv的用法

2022-04-12 19:44:07 浏览数 (1)

前言

我们在运行 Python 项目的时候经常会遇到一些版本问题,例如 A 项目依赖于 Django 1.5,而 B 项目又依赖 Django 2.0,而我们的系统却只有一个 Python 解释器,我们所有的包都被装在了 Python 安装目录的 site-packages 目录下,所以 Django 只能是某个特定的版本,所以这样就会导致运行的时候导致 A 或 B 项目出现兼容问题。为了解决这个问题,我们可能会使用 virtualenv 来为项目创建一套独立的 Python 运行环境,或者我们可能会使用 Docker 容器来实现不同项目的隔离运行,但总的来说,它们使用起来其实并没有那么方便。另外在进行 Python 包管理时,requirements.txt 这样的包依赖标识文件也显得很鸡肋,在某些情况下可能会带来一些麻烦。为了解决这些问题,一个更加使用方便的包管理工具诞生了,叫做 Pipenv,接下来就让我们一起来了解一下它的用法。

简介

Pipenv,它的项目简介为 Python Development Workflow for Humans,是 Python 著名的 requests 库作者 kennethreitz 写的一个包管理工具,它可以为我们的项目自动创建和管理虚拟环境并非常方便地管理 Python 包,现在它也已经是 Python 官方推荐的包管理工具。

Pipenv 我们可以简单理解为 pip 和 virtualenv 的集合体,它可以为我们的项目自动创建和管理一个虚拟环境。virtualenv 在使用时我们需要手动创建一个虚拟环境然后激活,Pipenv 会自动创建。另外我们之前可能使用 requirements.txt 文件来标识项目所需要的依赖,但是这样会带来一些问题,如有的 requirements.txt 中只是将库名列出来了,没有严格指定版本号,这样就可能会导致不同时间安装的库版本是不同的,如 requirements.txt 文件中对 Django 的依赖只写了一个 django,可能在 2016 年的时候运行安装会安装 Django 的 1.x 版本,到了 2017 年就会安装 Django 的 2.x 版本,所以可能导致一些麻烦。为了解决这个问题,Pipenv 直接弃用了 requirements.txt,会同时它会使用一个叫做 Pipfile 和 Pipfile.lock 的文件来管理项目所需的依赖包,而不再是简单地使用 requirements.txt 文件来记录项目所需要的依赖。

总的来说,Pipenv 可以解决如下问题:

  • 我们不需要再手动创建虚拟环境,Pipenv 会自动为我们创建,它会在某个特定的位置创建一个 virtualenv 环境,然后调用 pipenv shell 命令切换到虚拟环境。
  • 使用 requirements.txt 可能会导致一些问题,所以 Pipenv 使用 Pipfile 和 Pipfile.lock 来替代之,而且 Pipfile 如果不存在的话会自动创建,而且在安装、升级、移除依赖包的时候会自动更新 Pipfile 和 Pipfile.lock 文件。
  • 广泛使用 Hash 校验,保证安全性。
  • 可以更清晰地查看 Python 包及其关系,调用 pipenv graph 即可呈现,结果简单明了。
  • 可通过自动加载 .env 读取环境变量,简化开发流程。

安装

本文内容基于 Python 3.6 说明,默认的 Python 解释器命令为 python3,包管理工具命令为 pip3

Pipenv 是基于 Python 开发的包,所以可以直接用 pip 来安装,命令如下:

代码语言:javascript复制
pip3 install pipenv

另外还有多种安装方式,如 Pipsi、Nix、Homebrew,安装方式可以参考:http://pipenv.readthedocs.io/en/latest/#install-pipenv-today。

基本使用

首先我们可以新建一个项目,例如叫做 PipenvTest,然后新建一个 Python 脚本,例如叫 main.py,内容为:

代码语言:javascript复制
import django
print(django.get_version())

直接用系统的 Python3 运行此脚本:

代码语言:javascript复制
python3 main.py

结果如下:

代码语言:javascript复制
1.11

我们可以看到系统安装的 Django 版本是 1.11。但是我们想要本项目基于 Django 2.x 开发,当然我们可以选择将系统的 Django 版本升级,但这样又可能会影响其他的项目的运行,所以这并不是一个好的选择。为了不影响系统环境的 Django 版本,所以我们可以用 Pipenv 来创建一个虚拟环境。

在该目录下,输入 pipenv 命令即可查看命令的完整用法:

代码语言:javascript复制
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.

接下来我们首先验证一下当前的项目是没有创建虚拟环境的,调用如下命令:

代码语言:javascript复制
pipenv --venv

结果如下:

代码语言:javascript复制
No virtualenv has been created for this project yet!

这说明当前的项目尚未创建虚拟环境,接下来我们利用 Pipenv 来创建一个虚拟环境:

代码语言:javascript复制
pipenv --three

or 

pipenv --python 3.6

都可以创建一个 Python3 的虚拟环境,–three 代表创建一个 Python3 版本的虚拟环境,–python 则可以指定特定的 Python 版本,当然 --two 则创建一个 Python2 版本的虚拟环境,但前提你的系统必须装有该版本的 Python 才可以。

如果报错

代码语言:javascript复制
C:softpycharmpycharmcodezxf_projectz_testpyproxy-async>pipenv --three
Creating a virtualenv for this project…
Pipfile: C:softpycharmpycharmcodezxf_projectz_testpyproxy-asyncPipfile
Using C:/soft/python3.6/python.exe (None) to create virtualenv…
[==  ] Creating virtual environment...The path C:/soft/python3.6/python.exe (from --python=C:/soft/python3.6/python.exe) does not exist

增加参数–python= python3安装路径

代码语言:javascript复制
pipenv install --python=d:/soft/python3.6/python.exe

执行完毕之后,样例输出如下:

代码语言:javascript复制
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…
#Pipenv 利用 /usr/local/bin/python3 作为 virtualenv 的解释器
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 时是完全一样的,只不过文件夹的位置不同而已。

接下来我们可以切换到该虚拟环境下执行命令,执行如下命令即可:

代码语言:javascript复制
pipenv shell

执行完毕之后样例输出如下:

代码语言:javascript复制
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 可执行文件的路径,命令如下:

代码语言:javascript复制
(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 解释器,这时我们重新执行刚才的脚本,命令如下:

代码语言:javascript复制
(PipenvTest-VSTVh89E) CQC-MAC% python3 main.py

这时我们可以发现报了如下错误:

代码语言:javascript复制
Traceback (most recent call last):
  File "main.py", line 1, inimport django
ModuleNotFoundError: No module named 'django'

这其实是因为新的虚拟环境没有安装任何的 Python 第三方包,实际上如果直接使用 virtualenv 时也是这样的结果。这是因为新的虚拟环境是一个全新的 Python 环境,它默认只包含了 Python 内置的包以及 pip、wheel、setuptools 包,其他的第三方包都没有安装。

这时我们可以使用 Pipenv 来安装 django 包,命令如下:

代码语言:javascript复制
pipenv install django

运行后输出结果如下:

代码语言:javascript复制
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 文件,内容如下:

可以看到里面标识了 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 版本信息了:

代码语言:javascript复制
(PipenvTest-VSTVh89E) CQC-MAC% python3 main.py

结果如下:

代码语言:javascript复制
2.0.2

这样我们就成功安装了 Django 2.x 了,和系统的 Django 1.11 没有任何冲突。

在此模式的命令行下,我们就可以使用虚拟环境下的 Python 解释器,而且所安装的依赖包对外部系统没有任何影响,而且使用 Pipfile 和 Pipfile.lock 来管理项目的依赖更加方便和健壮。

如果想要退出虚拟环境,只需要输入 exit 命令即可:

代码语言:javascript复制
(PipenvTest-VSTVh89E) CQC-MAC% exit
➜  PipenvTest python3 main.py 
1.11

输入退出命令之后,我们重新再运行此脚本,就会重新使用系统的 Python 解释器,Django 版本又重新回到了 1.11。

由此可以看来,有了 Pipenv,我们可以使用 Pipfile 和 Pipfile.lock 来方便地管理和维护项目的依赖包,而且可以实现虚拟环境运行,避免了包冲突问题,可谓一举两得。

常用命令

代码语言:javascript复制
pipenv --where                 列出本地工程路径
pipenv --venv                  列出虚拟环境路径
pipenv --py                    列出虚拟环境的Python可执行文件
pipenv install                 创建虚拟环境
pipenv isntall [moduel]        安装包
pipenv install [moduel] --dev  安装包到开发环境
pipenv uninstall[module]       卸载包
pipenv uninstall --all         卸载所有包
pipenv graph                   查看包依赖
pipenv lock                    生成lockfile
pipenv run python [pyfile]     运行py文件
pipenv --rm                    删除虚拟环境

上文我们介绍了 Pipenv 的基本操作,下面我们再介绍一下它的一些常用命令。

运行你的代码

为了激活与你的Python项目相关联的虚拟环境,你可以使用简单地shell命令,比如

代码语言:javascript复制
 $ pipenv run which python

将在你的虚拟环境中运行which python命令,并显示与你的虚拟环境相关联的python可执行文件所在的路径。 这是在虚拟环境中运行你自己的Python代码的一个简单方法,

代码语言:javascript复制
 $ pipenv run python my_prject.py

如果你不想每次运行Python时都输入这么多,你可以在shell中设置一个别名,例如,

代码语言:javascript复制
 $ alias prp = "pipenv run python"

虚拟环境路径

我们可以使用 --venv 参数来获得虚拟环境路径:

代码语言:javascript复制
pipenv --venv

样例输出如下:

代码语言:javascript复制
/Users/CQC/.local/share/virtualenvs/PipenvTest-VSTVh89E

可见这个路径是一个标准的路径,Pipenv 会把虚拟环境统一放到 virtualenvs 文件夹下,而不是本项目路径下。

Python 解释器路径

要获取虚拟环境 Python 解释器路径,可以使用 --py 参数:

代码语言:javascript复制
pipenv --py

样例输出如下:

代码语言:javascript复制
/Users/CQC/.local/share/virtualenvs/PipenvTest-VSTVh89E/bin/python

加载系统 Python 包

默认情况下,新创建的虚拟环境是不包含任何第三方包的,但我们也可以开启加载系统 Python 包功能,使用 --site-packages 即可:

代码语言:javascript复制
pipenv --site-packages

这样创建的虚拟环境便可以使用系统已安装的 Python 包了。

开启虚拟环境

要开启虚拟环境只需要执行如下命令:

代码语言:javascript复制
pipenv shell

这样就可以进入虚拟环境,此时运行的 python、python3 命令都是虚拟环境下的。

安装 Python 包

安装 Python 包我们不再需要 pip 来安装,直接使用 Pipenv 也可安装,如安装 requests,命令如下:

代码语言:javascript复制
pipenv install requests

安装完成之后会同时更新项目目录下的 Pipfile 和 Pipfile.lock 文件。

有时候一些 Python 包是仅仅开发环境需要的,如 pytest,这时候我们通过添加 --dev 参数即可,命令如下:

代码语言:javascript复制
pipenv install pytest --dev

这时候,pytest 的依赖便会记录在 Pipfile 的 [dev-packages] 区域:

代码语言:javascript复制
[dev-packages]
pytest = "*"

获取包依赖

我们可以使用命令来清晰地呈现出当前安装的 Python 包版本及之间的依赖关系,命令如下:

代码语言:javascript复制
pipenv graph

样例结果如下:

代码语言:javascript复制
Django==2.0.2
  - pytz [required: Any, installed: 2018.3]
pytest==3.4.1
  - attrs [required: >=17.2.0, installed: 17.4.0]
  - pluggy [required: <0.7,>=0.5, installed: 0.6.0]
  - py [required: >=1.5.0, installed: 1.5.2]
  - setuptools [required: Any, installed: 38.5.1]
  - six [required: >=1.10.0, installed: 1.11.0]
requests==2.18.4
  - certifi [required: >=2017.4.17, installed: 2018.1.18]
  - chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
  - idna [required: <2.7,>=2.5, installed: 2.6]
  - urllib3 [required: <1.23,>=1.21.1, installed: 1.22]

可以看到结果非常清晰,Django 当前安装了 2.0.2版本,依赖于 pytz 任何版本,已经安装了 2018.3 版本;pytest 已经安装了 3.4.1 版本,依赖 attrs>=17.2.0 版本,已经安装了 17.4.0 版本,另外还依赖 pluggy、py、setuptools、six 这些库。总之包的依赖关系一目了然。

卸载 Python 包

卸载 Python 包也非常简单,如卸载 requests 包,命令如下:

代码语言:javascript复制
pipenv uninstall requests

卸载完成之后,Pipfile 和 Pipfile.lock 文件同样会更新。

如果要卸载全部 Python 包,可以添加 --all 参数:

代码语言:javascript复制
pipenv uninstall --all

产生 Pipfile.lock

有时候可能 Pipfile.lock 文件不存在或被删除了,这时候我们可以使用如下命令生成:

代码语言:javascript复制
pipenv lock

以上便是一些常用的 Pipenv 命令,如果要查看更多用法可以参考其官方文档:https://docs.pipenv.org/#pipenv-usage。

结语

本文介绍了 Pipenv 的基本用法,作为 pip 和 virtualenv 的结合体,我们可以利用它更方便地创建和管理 Python 虚拟环境,还可以用更加科学的方式管理 Python 包,一举两得。

嗯,是时候抛弃 virtualenv 和 pip 了!

参考:https://cuiqingcai.com/5846.html https://blog.csdn.net/zhanun520jxx/article/details/81293987


Python3 venv 创建虚拟环境

简介

Python3.3以上的版本通过venv模块原生支持虚拟环境,可以代替Python之前的virtualenv。

该venv模块提供了创建轻量级“虚拟环境”,提供与系统Python的隔离支持。每一个虚拟环境都有其自己的Python二进制(允许有不同的Python版本创作环境),并且可以拥有自己独立的一套Python包。

需要注意的是,在Python3.3中使用”venv”命令创建的环境不包含”pip”,你需要进行手动安装。在Python3.4中改进了这一个缺陷。

创建虚拟环境

在当前目录创建虚拟环境:

代码语言:javascript复制
$ python -m venv .

下面是”venv”的详细使用参数:

代码语言:javascript复制
usage: venv [-h] [--system-site-packages] [--symlinks] [--clear]
            [--upgrade] [--without-pip] ENV_DIR [ENV_DIR ...]

Creates virtual Python environments in one or more target directories.

positional arguments:
  ENV_DIR             A directory to create the environment in.

optional arguments:
  -h, --help             show this help message and exit
  --system-site-packages Give access to the global site-packages dir to the
                         virtual environment.
  --symlinks             Try to use symlinks rather than copies, when symlinks
                         are not the default for the platform.
  --copies               Try to use copies rather than symlinks, even when
                         symlinks are the default for the platform.
  --clear                Delete the environment directory if it already exists.
                         If not specified and the directory exists, an error is
                         raised.
  --upgrade              Upgrade the environment directory to use this version
                         of Python, assuming Python has been upgraded in-place.
  --without-pip          Skips installing or upgrading pip in the virtual
                         environment (pip is bootstrapped by default)

激活虚拟环境

在Posix标准平台下:

代码语言:javascript复制
$ source <venv>/bin/activate

在Windows cmd下:

代码语言:javascript复制
C:> <venv>/Scripts/activate.bat

在Windows PowerShell下:

代码语言:javascript复制
PS C:> <venv>/Scripts/Activate.ps1

测试虚拟环境

激活虚拟环境后,在命令行会提示当前虚拟环境的名称,就表示激活成功了。

在当前虚拟环境中安装numpy:

代码语言:javascript复制
$ pip install numpy

当前安装的numpy包与系统中的不会冲突,下面进行测试:

代码语言:javascript复制
$ python
>>> import numpy
>>> print(numpy)

如果输出了numpy的包路径就表示一切正常。

官方文档参考

https://docs.python.org/3/library/venv.html

0 人点赞