利用pipenv和pyenv管理多个相互独立的Python虚拟开发环境


Posted in Python onNovember 01, 2020

我们经常会遇到这样的开发需求,比如你手头有多个开发项目,其中项目A要求用python3.7,项目B需要用python3.6,有要求项目A和项目B依赖包相互独立,互不干扰。为了满足这样的开发需求,我们需要在自己的电脑上安装多个Python版本,并且项目之间进行环境隔离。要想安装多个Python版本,可以利用pyenv这个好用的工具,对于建立多个项目之间隔离的开发环境,可以借助于pipenv这个更加好用的包管理工具。

这篇文章将给大家介绍如何利用pyenv和pipenv来管理我们的python开发环境,主要讲两个核心内容:
1.如何在同一台电脑上管理多个版本Python;
2.为每一个项目建立相互隔绝的虚拟环境。

01 — 安装多个Python版本

我们自己开发的多个项目或者从github上clone的项目,可能依赖不同的Python解释器。因此,我们要想运行这些项目,在工作电脑上就要安装不同版本的Python。

pyenv是Python版本管理工具,利用它可以在同一台电脑上安装多个版本的Python,这个过程非常简单。

1.1、安装或升级pyenv

首先安装pyenv,如果你是Mac电脑,那么推荐使用Homebrew来安装。

$ brew update && brew install pyenv

要想升级pyenv,则可以执行:

$ brew update && brew upgrade pyenv

如果不是Mac电脑,那么就用github方式来安装:

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
$ exec "$SHELL"

这种安装方式的详细说明,还是建议大家参考官方文档:https://github.com/pyenv/pyenv#basic-github-checkout。

对于github安装的pyenv,可以按下面方式进行升级:

$ cd $(pyenv root)
$ git fetch
$ git tag
v1.2.18
$ git checkout v1.2.18

pyenv安装完成后,需要将$(pyenv root)/shims添加到PATH变量前面,这一步非常关键。

$ echo 'export PATH="$(pyenv root)/shims:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile

1.2、用pyenv安装Python

安装完pyenv,可以安装Python啦,一共需要两步。

$ pyenv install 3.7.7
$ pyenv rehash

执行命令pyenv versions查看安装结果。

$ pyenv versions
 system
* 3.7.7 (set by /Users/chunming.liu/.pyenv/version)

可以看到,已经成功安装了Python 3.7.7,安装的位置在/Users/chunming.liu/.pyenv。

1.3、切换Python版本

可以通过pyenv global或者pyenv local切换Python版本。pyenv global属于全局切换,切换完成后,在系统中任何地方执行python,你会发现都是同样的Python版本。

$ pyenv global 3.7.7
$ pyenv versions
 system
* 3.7.7 (set by /Users/chunming.liu/.pyenv/version)

可以看到,3.7.7前面有一个星号,说明成功切换到了3.7.7版本,可以执行一下python来验证一下:

$ python
Python 3.7.7 (default, Apr 12 2020, 12:31:11)
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

pyenv local属于局部切换,只能修改当前目录下的Python版本,出了当前目录则失效。

接下来,开始为每个项目建立独立的开发环境。

02 — 用Pipenv创建虚拟环境

Pipenv是Python官方推荐的包管理工具。它综合了 virtualenv , pip 和 pyenv 三者的功能。你可以使用pipenv这一个工具来安装、卸载、跟踪和记录依赖性,并创建、使用和组织你的虚拟环境。

2.1、安装和升级pipenv

如果你是Mac电脑,那么推荐使用Homebrew来安装和升级pipenv:

$ brew update && brew install pipenv
$ brew update && brew upgrade pipenv

也可以通过pip来安装和升级pipenv:

$ pip install pipenv
$ pip install --upgrade pipenv

2.2、为项目建立虚拟环境

进入到项目目录中,通过下面的指令为项目创建虚拟环境。

$ mkdir pipenv_demo
$ cd pipenv_demo
$ pipenv --python 3.7.7
Creating a virtualenv for this project…
Pipfile: /Users/chunming.liu/work/pipenv_demo/Pipfile
Using /Users/chunming.liu/.pyenv/versions/3.7.7/bin/python3 (3.7.7) to create virtualenv…
⠙ Creating virtual environment...Using base prefix '/Users/chunming.liu/.pyenv/versions/3.7.7'
New python executable in /Users/chunming.liu/.local/share/virtualenvs/pipenv_demo-RYMSREda/bin/python3
Also creating executable in /Users/chunming.liu/.local/share/virtualenvs/pipenv_demo-RYMSREda/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /Users/chunming.liu/.pyenv/versions/3.7.7/bin/python3
​
✔ Successfully created virtual environment!
Virtualenv location: /Users/chunming.liu/.local/share/virtualenvs/pipenv_demo-RYMSREda

上面的操作,给pipenv_demo这个项目初始化了一个Python 3.7.7的虚拟环境,并在项目录下生成一个项目依赖包文件Pipefile。如果系统中没有3.7.7版本的Python,pipenv会调用pyenv来安装对应的Python的版本。

默认地,虚拟环境会创建在~/.local/share/virtualenvs目录里面。我们也可以通过pipenv --venv查看项目的虚拟环境目录。可以通过 pipenv --rm 删除虚拟环境。

如果想更改虚拟环境的目录,可以在 .bashrc 或 .bash_profile 中,设置环境变量WORKON_HOME,指定虚拟环境的目录所在位置,比如想将虚拟环境放到~/.venvs目录,则可以执行下面的命令。

$ echo 'export WORKON_HOME=~/.venvs' >> ~/.bash_profile
$ source ~/.bash_profile

如果希望在项目目录下创建虚拟环境目录(.venv),需要在 .bashrc 或 .bash_profile 中配置环境变量PIPENV_VENV_IN_PROJECT:

$ echo 'export PIPENV_VENV_IN_PROJECT=1' >> ~/.bash_profile
$ source ~/.bash_profile

03 — 用Pipenv管理依赖包

pipenv使用 Pipfile 和 Pipfile.lock 来管理依赖包,并且在使用pipenv添加或删除包时,自动维护 Pipfile 文件,同时生成 Pipfile.lock 来锁定安装包的版本和依赖信息。相比pip需要手动维护requirements.txt 中的安装包和版本,具有很大的进步。

3.1 安装依赖包

为项目安装依赖包到虚拟环境中,使每个项目拥有相互独立的依赖包,是非常不错的Python的开发实践。安装依赖包到虚拟环境中的方法:

$ pipenv install pytest
Installing pytest…
Adding pytest to Pipfile's [packages]…
✔ Installation Succeeded
Pipfile.lock not found, creating…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
✔ Success!
Updated Pipfile.lock (1c4d3d)!
Installing dependencies from Pipfile.lock (1c4d3d)…
 ?  ???????????????????????????????? 11/11 — 00:00:16
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

执行完上面的命令后,检查一下是否安装成功:

$ pipenv graph
pytest==5.4.1
 - attrs [required: >=17.4.0, installed: 19.3.0]
 - importlib-metadata [required: >=0.12, installed: 1.6.0]
  - zipp [required: >=0.5, installed: 3.1.0]
 - more-itertools [required: >=4.0.0, installed: 8.2.0]
 - packaging [required: Any, installed: 20.3]
  - pyparsing [required: >=2.0.2, installed: 2.4.7]
  - six [required: Any, installed: 1.14.0]
 - pluggy [required: >=0.12,<1.0, installed: 0.13.1]
  - importlib-metadata [required: >=0.12, installed: 1.6.0]
   - zipp [required: >=0.5, installed: 3.1.0]
 - py [required: >=1.5.0, installed: 1.8.1]
 - wcwidth [required: Any, installed: 0.1.9]

可看到已经安装了pytest,还列出了pytest的依赖包。

观察项目的根目录下,又多了一个Pipfile.lock文件。这两个文件记录了此项目的依赖包,这两个文件的区别是 Pipfile中安装的包不包含包的具体版本号,而Pipfile.lock是包含包的具体的版本号的。如果不想产生Pipfile.lock文件,在安装依赖包的时候,加上?skip-lock选项即可。

打开依赖包文件Pipefile,可以看到python_version = “3.7”,说明这个项目是基于Python 3.7版本的。package部分列出来了项目的依赖包是bpytest = “*”,星号代表最新版本。

而Pipfile.lock是包含安装的依赖包具体的版本号,可以看到本次安装的pytest是5.4.1版本,并且它的依赖包的版本也列出来了。

$ cat Pipfile.lock
{
  "_meta": {
    "hash": {
      "sha256": "828b8ad012f4c8773e6e61e3ac2be0ffcd7540fd7ed175a8355676c8e31c4d3d"
    },
    "pipfile-spec": 6,
    "requires": {
      "python_version": "3.7"
    },
    "sources": [
      {
        "name": "pypi",
        "url": "https://pypi.org/simple",
        "verify_ssl": true
      }
    ]
  },
  "default": {
    "attrs": {
      "hashes": [
        "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c",
        "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"
      ],
      "version": "==19.3.0"
    },
    "importlib-metadata": {
      "hashes": [
        "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f",
        "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e"
      ],
      "markers": "python_version < '3.8'",
      "version": "==1.6.0"
    },
    "more-itertools": {
      "hashes": [
        "sha256:5dd8bcf33e5f9513ffa06d5ad33d78f31e1931ac9a18f33d37e77a180d393a7c",
        "sha256:b1ddb932186d8a6ac451e1d95844b382f55e12686d51ca0c68b6f61f2ab7a507"
      ],
      "version": "==8.2.0"
    },
    "packaging": {
      "hashes": [
        "sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3",
        "sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752"
      ],
      "version": "==20.3"
    },
    "pluggy": {
      "hashes": [
        "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0",
        "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"
      ],
      "version": "==0.13.1"
    },
    "py": {
      "hashes": [
        "sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa",
        "sha256:c20fdd83a5dbc0af9efd622bee9a5564e278f6380fffcacc43ba6f43db2813b0"
      ],
      "version": "==1.8.1"
    },
    "pyparsing": {
      "hashes": [
        "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
        "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
      ],
      "version": "==2.4.7"
    },
    "pytest": {
      "hashes": [
        "sha256:0e5b30f5cb04e887b91b1ee519fa3d89049595f428c1db76e73bd7f17b09b172",
        "sha256:84dde37075b8805f3d1f392cc47e38a0e59518fb46a431cfdaf7cf1ce805f970"
      ],
      "index": "pypi",
      "version": "==5.4.1"
    },
    "six": {
      "hashes": [
        "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a",
        "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"
      ],
      "version": "==1.14.0"
    },
    "wcwidth": {
      "hashes": [
        "sha256:cafe2186b3c009a04067022ce1dcd79cb38d8d65ee4f4791b8888d6599d1bbe1",
        "sha256:ee73862862a156bf77ff92b09034fc4825dd3af9cf81bc5b360668d425f3c5f1"
      ],
      "version": "==0.1.9"
    },
    "zipp": {
      "hashes": [
        "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b",
        "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"
      ],
      "version": "==3.1.0"
    }
  },
  "develop": {}
}

3.2 提高依赖包安装速度

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

如果想通过Pypi的国内镜像安装依赖包,可以在安装软件包时,指定?pypi-mirror,比如通过清华大学镜像安装flask软件包:

$ pipenv install --pypi-mirror https://pypi.tuna.tsinghua.edu.cn/simple flask

为了避免每次都要指定?pypi-mirror,我一般会在创建好Pipfile以后,将文件中 source 块下的 url 字段,设置为国内的 pypi 源,我推荐的是清华的Pypi源或者阿里源,具体设置如下:

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

3.3 删除依赖包

如果是要删除虚拟环境中的第三方包,执行

$ pipenv uninstall pytest

3.4 安装项目所有的依赖包

用git管理项目时候,要把Pipfile和Pipfile.lock加入版本跟踪。这样clone了这个项目的同学,只需要执行

$ pipenv install

就可以安装所有的Pipfile中 [packages]部分列出来的包了,并且自动为项目在自己电脑上创建了虚拟环境。

3.5 安装pipefile.lock中的依赖包

上面的方法都是安装Pipfile中列出来的第三方包的最新版本,如果是想安装Pipfile.lock中固定版本的第三方依赖包,需要执行:

$ pipenv install --ignore-pipfile

3.6 安装requirements.txt里面的依赖包

如果项目之前使用requirements.txt来管理依赖的,那么使用pipenv安装所有依赖可以采用类似pip的方法:

$ pipenv install -r requirements.txt

04 — 使用虚拟环境进行开发

虚拟环境创建好了之后,就可以在里面进行开发了。

如果在命令行下开发,则在项目目录下执行pipenv shell,就进入到了虚拟环境中,在这个环境中,已经包含安装过的所有依赖包了,接下来就可以利用这些依赖包进行开发工作了。

$ pipenv shell
Launching subshell in virtual environment…
bash-3.2$ . /Users/chunming.liu/.local/share/virtualenvs/pipenv_demo-RYMSREda/bin/activate
(pipenv_demo) bash-3.2$ python
Python 3.7.7 (default, Apr 12 2020, 12:31:11)
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pytest
>>>

如果是用Pycharm进行开发,就更简单了,直接用Pycharm打开项目即可。可以从Pycharm中的左侧导航栏里面看到External Libraries显示的是虚拟环境中的Python解释器了。

在虚拟环境中执行开发好的程序,有两种方式,一种是前面提到的先执行pipenv shell进入到虚拟环境后,再执行python程序;另一种方式,则是执行pyenv run,比如在虚拟环境中执行基于pytest框架编写的测试用例,只需要执行下面的命令即可:

$ pipenv run py.test

04 — 总结

本文给大家介绍了如何使用pyenv安装多个版本Python,如何在不同的Python版本间切换。还介绍了一种Python官方推荐使用的包管理工具pipenv,它结合pyenv和pip和virtualenv的优点于一身,可以帮我们管理项目的虚拟环境、管理项目的依赖包。

在这里插入图片描述

非常建议大家尝试一下pyenv和pipenv。在实践中,推荐大家将Pipfile和Pipfile.lock加入版本跟踪,不要将虚拟环境.venv加入版本管理,因为这个包比较大,而且可以pipenv install方式重建。为每一个项目项目建立独立的虚拟环境,为每一个项目使用Pipfile管理依赖是一个非常好的实践。

参考资料

https://github.com/pyenv/pyenv

https://github.com/pypa/pipenv

https://packaging.python.org/tutorials/managing-dependencies/#installing-pipenv

https://hackersandslackers.com/pipenv-python-environment-management/

到此这篇关于利用pipenv和pyenv管理多个相互独立的Python虚拟开发环境的文章就介绍到这了,更多相关pipenv和pyenv管理多Python虚拟环境内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
用Python制作简单的朴素基数估计器的教程
Apr 01 Python
Python 'takes exactly 1 argument (2 given)' Python error
Dec 13 Python
Python实现简单的文本相似度分析操作详解
Jun 16 Python
解决python中 f.write写入中文出错的问题
Oct 31 Python
python实现向微信用户发送每日一句 python实现微信聊天机器人
Mar 27 Python
python 中的[:-1]和[::-1]的具体使用
Feb 13 Python
python中68个内置函数的总结与介绍
Feb 24 Python
Python 格式化打印json数据方法(展开状态)
Feb 27 Python
python读取文件指定行内容实例讲解
Mar 02 Python
Python实现Excel自动分组合并单元格
Feb 22 Python
pytorch--之halfTensor的使用详解
May 24 Python
Python图片检索之以图搜图
May 31 Python
Python经纬度坐标转换为距离及角度的实现
Nov 01 #Python
详解Anaconda安装tensorflow报错问题解决方法
Nov 01 #Python
python Cartopy的基础使用详解
Nov 01 #Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
Oct 31 #Python
关于python中导入文件到list的问题
Oct 31 #Python
python批量检查两个对应的txt文件的行数是否一致的实例代码
Oct 31 #Python
Python在线和离线安装第三方库的方法
Oct 31 #Python
You might like
ThinkPHP框架整合微信支付之Native 扫码支付模式二图文详解
2019/04/09 PHP
JQuery的ajax基础上的超强GridView展示
2009/09/18 Javascript
jQuery选择器的工作原理和优化分析
2011/07/25 Javascript
jQuery实现鼠标可拖动调整表格列宽度
2014/05/26 Javascript
浅谈javascript中createElement事件
2014/12/05 Javascript
jQuery中:animated选择器用法实例
2014/12/29 Javascript
jqGrid表格应用之新增与删除数据附源码下载
2015/12/02 Javascript
jQuery插件编写步骤详解
2016/06/03 Javascript
js实现上传文件添加和删除文件选择框
2016/10/24 Javascript
vue父组件中获取子组件中的数据(实例讲解)
2017/09/27 Javascript
jQuery实现简单的回到顶部totop功能示例
2017/10/16 jQuery
nodeJS微信分享
2017/12/20 NodeJs
css配合JavaScript实现tab标签切换效果
2018/10/11 Javascript
微信小程序实现星星评价效果
2018/11/02 Javascript
基于element-ui组件手动实现单选和上传功能
2018/12/06 Javascript
react MPA 多页配置详解
2019/10/18 Javascript
Python中的赋值、浅拷贝、深拷贝介绍
2015/03/09 Python
用十张图详解TensorFlow数据读取机制(附代码)
2018/02/06 Python
python实现定时压缩指定文件夹发送邮件
2020/12/22 Python
Python实现多态、协议和鸭子类型的代码详解
2019/05/05 Python
linux环境中没有网络怎么下载python
2019/07/07 Python
python代码编写计算器小程序
2020/03/30 Python
Python3实现zip分卷压缩过程解析
2019/10/09 Python
使用phonegap获取设备的一些信息方法
2017/03/31 HTML / CSS
使用html5新特性轻松监听任何App自带返回键的示例
2018/03/13 HTML / CSS
Under Armour安德玛中国官网:美国高端运动科技品牌
2018/03/09 全球购物
Camper鞋西班牙官方网上商店:西班牙马略卡岛的鞋类品牌
2019/03/14 全球购物
Coccinelle官网:意大利的著名皮具品牌
2019/05/15 全球购物
大学四年规划书范文
2013/12/27 职场文书
国培计划培训感言
2014/03/11 职场文书
还款承诺书范文
2014/05/20 职场文书
竞选宣传委员演讲稿
2014/05/24 职场文书
教师工作自我鉴定范文
2014/09/14 职场文书
2014年重阳节老干部座谈会局领导发言稿
2014/09/25 职场文书
伊索寓言读书笔记
2015/06/30 职场文书
Python爬虫入门案例之爬取去哪儿旅游景点攻略以及可视化分析
2021/10/16 Python