1. 程式人生 > 程式設計 >利用pipenv和pyenv管理多個相互獨立的Python虛擬開發環境

利用pipenv和pyenv管理多個相互獨立的Python虛擬開發環境

我們經常會遇到這樣的開發需求,比如你手頭有多個開發專案,其中專案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,"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虛擬環境內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!