天天看點

使用pyenv和pyenv-virtualenv管理python 版本

背景:

本來我是用

brew switch python xxxx

+

virtualenv

+

virtualenvwrapper

來管理版本的。但是由于更早之前對于版本管理沒有概念,導緻系統有些混亂。除了系統自帶的python 2.7.17之外,還有homebrew安裝的[email protected] (2.7.17)/3.6.5_1/3.7.6_1。 最終出了一點小問題,那就是

virtualenvwrapper

建立虛拟環境後,雖然

python -V

pip install

都OK,但是

python-config

指令還是沒有正常切換,而是連接配接到了

/usr/local/bin/python-config

上面,而這個又連接配接到了系統的

/usr/bin/python-config

上面,不論怎麼運作

python-config --config-dir

都會提示

Usage: /usr/local/bin/python-config [--prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--help]

的python上面,

python2-config

python3-config

都能正常運作。而恰好我的系統自帶的

python-config

指令出了問題,不能正确執行。
猜想:在某些需要python-config的場景下(比如cmake編譯),可以使用

--with-python-config-dir=/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config

來繞過這個錯誤?

好吧言歸正傳。首先

pyenv

可以管理和切換系統全局和局部python版本,

pyenv-virtualenv

管理虛拟環境。它們可以從Homebrew安裝,也可以從git倉庫克隆安裝,本文隻涉及Hombrew安裝,git安裝請參考這篇文章。Linux安裝請參考下面。

1.通過Brew安裝和激活環境

#安裝
brew install pyenv pyenv-virtualenv
           

然後使用者profile添加如下内容,然後source之使其生效:

eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
           

2. pyenv常用指令

pyenv versions #列出所有被 pyenv 管理的 python 版本,目前使用的版本前會用 * 标出
pyenv install --list # 列出可安裝版本
pyenv install <version> # 安裝對應版本
pyenv install -v <version> # 安裝對應版本,若發生錯誤,可以顯示詳細的錯誤資訊
pyenv uninstall [-f|--force] <version> #解除安裝某個版本的 python,-f|--force 選項的作用是強制删除某版本的 python,不需要确認,如果該版本不存在,也不會給出錯誤資訊。
pyenv which python # 顯示目前python安裝路徑
pyenv global <version> # (不推薦)設定預設Python版本,可能會搞亂系統依賴
pyenv local <version> # 目前路徑建立一個.python-version, 以後進入這個目錄自動切換為該版本(我更推薦使用pyen-virtualenv管理版本)
pyenv local --unset #取消設定目前目錄的 python 版本
pyenv shell <version> # 目前shell的session中啟用某版本,優先級高于global 及 local
pyenv shell --unset #取消設定目前 shell 的 python 版本
pyenv shell #顯示目前 shell 使用的 python 版本
export PYENV_VERSION=<version> #設定環境變量 PYENV_VERSION 的值為指定版本,也可以直接設定環境變量 PYENV_VERSION 的值,效果一樣
pyenv rehash #更新目錄 shims 的内容,以使 pyenv 知道它所管理的 python 版本的最新資訊
           

3. 使 pyenv 暫時失效

注釋掉profile裡面的這兩句:

eval "$(pyenv init -)"

eval "$(pyenv virtualenv-init -)"

。重新source profile或者重新打開terminal即可。

4. pyenv-virtualenv常用指令

pyenv virtualenv env # 從預設版本建立虛拟環境env
pyenv virtualenv 3.6.10 py3cv4 # 建立3.6.4版本的虛拟環境,名稱為py3cv4
pyenv virtualenv --system-site-packages py3cv4 #從預設版本建立虛拟環境py3cv4,并且繼承系統的site-packages
pyenv activate py3cv4 # 激活 py3cv4 這個虛拟環境
pyenv deactivate # 停用目前的虛拟環境
pyenv uninstall py3cv4 # 删除 py3cv4 這個虛拟環境
           

5. 自動激活虛拟環境

# 可以配合pyenv local 實作自動激活虛拟環境
# 比如在 ~/opencv/目錄下,我希望進入這個目錄就自動激活`py3cv4`這個虛拟環境
#自動激活虛拟環境
pyenv local py3cv4  #在希望自動激活此虛拟環境的目錄下執行
#取消目前目錄自動激活虛拟環境
pyenv local --unset
           

折騰完這個之後。我終于可以和系統的python說再見了。

Tips:
  1. PYENV_DEBUG=1

    參數可以看到更多資訊用于debug:

    PYENV_DEBUG=1 pyenv virtualenv --system-site-packages sandbox

  2. 你可能會在進入pyenv虛拟環境的時候看到這個提示:

    yenv-virtualenv: prompt changing will be removed from future release. configure export PYENV_VIRTUALENV_DISABLE_PROMPT=1 to simulate the behavior.

    具體讨論看這裡,如果未來這個虛拟環境提示符真的會被取消,可以通過這個指令找回來

    export PS1='($(pyenv version-name)) '$PS1

如果你是從linux安裝(以wsl的Ubuntu為例)

有更簡單的方法(注意~/.bashrc修改為你對應的profile):

sudo apt-get update
sudo apt-get install python-pip git make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev


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

pyenv安裝python版本下載下傳太慢?

使用如下指令用國内源下載下傳pyenv對應python版本:

其中

v=3.7.3

代表版本号為

3.7.3

參考文獻:

python虛拟環境管理:pyvenv、pyenv、virtualenv

pyenv 安裝及常用指令

Common build problems · pyenv/pyenv Wiki

pyenv 安裝配置與國内鏡像加速 結合 virtualenv

pyenv/pyenv: Simple Python version management

pyenv/pyenv-virtualenv: a pyenv plugin to manage virtualenv (a.k.a. python-virtualenv)

Common build problems · pyenv/pyenv Wiki