”微服务一条龙“最佳指南-工具篇:初步使用Pipenv

##首先贴上Pipenv的主页

GitHub地址:https://github.com/pypa/pipenv
文档地址:https://docs.pipenv.org

  1. 背景介绍
    1.什么是Pipenv
    回答:包和版本管理的最好工具,pipenvPipfile 主要倡导者、requests 作者 Kenneth Reitz 写的一个命令行工具,主要包含了PipfilepipclickrequestsvirtualenvPipfilepipenv本来都是Kenneth Reitz的个人项目,后来贡献给了pypa组织。Pipfile是社区拟定的依赖管理文件,用于替代过于简陋的 requirements.txt 文件。
    2.Python有哪些包和版本管理工具?
    回答:pipvirtualenvpyenv
    3.这些工具和Pipenv的区别以及它类似与其他语言中的哪些工具?
    回答:
    (1)pip只是一个Python包管理的工具,也就是说它不能同时去管理项目的版本,举例来说,
    场景一:
    项目A和项目B,同时使用一个包,但是项目A需要使用包的1.0版本,项目B需要使用包的2.0版本
    场景二:
    项目A在开发阶段需要使用到单元测试模块,所以用到一些做测试的包,但是项目上线不需要这些包。
    这种场景需求就要求我们需要为不同的版本以及开发阶段提供不同虚拟环境。
    (2)virtualenv
    virtualenv 是一个创建隔绝的Python环境的工具。virtualenv创建一个包含所有必要的可执行文件的文件夹,用来使用Python工程所需的包。它的原理其实很简单,就是在创建完新的虚拟环境之后,在激活环境的同时,在环境变量里面加上了指定虚拟环境的Python路径而已
    讲到这里,我们有个疑惑,既然virtualenv这么好用了,为什么官方更推荐使用Pipenv呢,因为它在virtualenv之上又封装了一层,这就好像requestsurllib等网络库之后又封装了一层,更加人性化,以及更加丰富的、简洁的语法自然是更受欢迎,而且更加独特的是其在对于依赖的处理更加细节化,当下载一个新的包时,会自动对包加锁处理,检查其依赖包的包装情况。
    那么,在其他语言中是否有类似的项目呢,其实是有的。Pipenv也是借鉴于NodeNPMRubyGEM等等,大家感兴趣可以去看看他们的原理,我们会在之后的文章中来摸索一下他们的设计原理。

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,代表我们的虚拟环境成功安装了 Django2.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 了!

你可能感兴趣的:(”微服务一条龙“最佳指南)