#python

pyenvでのPython仮想環境の作り方まとめ

用語の整理

このへんの用語をすぐに忘れてごちゃごちゃになるのでメモ。

pyenv

Pythonのバージョンを管理する。2系と3系の環境分けだけでなく、3.4と3.5の環境分けなども含む。
基本的には手動でバージョンを切り替えることになるが、特定のディレクトリに移動すると自動でバージョンを切り替えるようにする設定(pyenv local) などもよく使われている。

virtualenv

Pythonのパッケージを管理する。Pythonそのもののバージョンは管理しない。

例えば、Django1.8 系を入れた環境と Django1.9系を入れた環境を分けたいときに使う。

pyenv-virtualenv

virtualenv を プラグインとして pyenv に組み込んだもの。→ Python のバージョンそのものの管理 + その中でパッケージの管理ができる。

使途の整理

2つの仮想環境の作り方(virtualenv系 と conda env系)

Pythonの仮想環境を作る場合、主にvertualenvconda envで環境を作る場合が多い。

  • ①pyenv + vertualenvで仮想環境を作る ・・・ pythonアプリなどを作るなど、自分の必要なパッケージを1つづつ自分でインストールしたい場合(科学計算用ライブラリなどが不要な場合 ex. numpyとかscipyとか)
  • ②pyenv + condaで仮想環境を作る・・・ 科学計算用ライブラリなどが必要な場合。主にデータ分析環境用に作ると便利かも。condaを使ってパッケージのインストールなどを行うため、面倒な依存関係のものも勝手に集めてきてくれ、比較的簡単にインストールできる。特に分析系のパッケージは依存関係が面倒なものが多いので、よくわからない人はこちらが楽かもしれない。 (自分の知らないものがごちゃごちゃと勝手にインストールされるのが嫌だ!という人は、上記の pyenv+virtualenvで環境を作り、1つずつ自分でインストールする方が良さそう。)

ここでは、両方の場合ともPython3系の環境を作ることを想定しています。

共通作業

MacOSでのpyenvのインストール

$ brew install pyenv

MacOS以外でのインストール

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv

環境変数の設定(カーネルがbashの場合)

$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
$ source ~/.bashrc

①pyenv + vertualenvで仮想環境を作る

pyenv-virtualenvのインストール

$ brew install pyenv-virtualenv

MacOS以外でのインストール

$ git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv

pyenv-virtualenvの環境設定

$ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
$ echo export PYENV_VIRTUALENV_DISABLE_PROMPT=1 >> ~/.bashrc
$ source ~/.bashrc

これでpyenv-virtualenvのインストールは完了

(※注)pyenv を有効にするため、ここで再ログイン (もしくはシェルの再起動)をしたほうが安全。sourceしてもいいですが、一旦ログアウトしてしまうのが安全っぽいです。

pyenvでインストールできる環境一覧をみる

$ pyenv install -l

試しにpython3.x系インストールしてみる。上記で確認して出てきた 3.6.5 をインストールしてみる

$ pyenv install 3.6.5

ダウンロードできたか確認

$ pyenv versions
* system (set by /Users/ysdyt/.pyenv/version)
  3.6.5

こうなってたらok

3.6.5の下にvirtualenvを作る

$ pyenv virtualenv 3.6.5 test  #ここでは test が環境の名前となる

もう一度 pyenv versionsすると以下のようになっているはず。

* system (set by /Users/ysdyt/.pyenv/version)
  3.6.5
  3.6.5/envs/test

環境の切り替え

$ pyenv global 3.6.5/envs/test

pyenv versionsしてアスタリスクの付く位置が変わっていたらok

  system (set by /Users/ysdyt/.pyenv/version)
  3.6.5
* 3.6.5/envs/test

確認

$ python3 -V  # -> Python 3.6.5

システムのpython環境に戻る

$ pyenv global system

作ったvirtualenv環境を消す場合

$ pyenv uninstall 3.6.5/envs/test

pyenv global と pyenv local

$ pyenv global 3.6.5/envs/test

のように globalを使って環境を切り替えた場合、どのディレクトリに移動しても環境は3.6.5/envs/testになります。

しかし、実用的には、「プロジェクトディレクトリ1の下にいるときは勝手にtest1という環境に切り替わってほしくて、プロジェクトディレクトリ2の下にいるときはtest2という環境に勝手に切り替わってほしい」というニーズがあります。(いちいちpyenv globalするのを忘れるときも多々あるし!)

そんなときに pyenv localを使います。

「プロジェクトディレクトリ1」まで移動して、その下で pyenv local test1 とすると、「プロジェクトディレクトリ1」に移動したときだけ自動でtest1環境に切り替わってくれるよう設定されます。便利!

②pyenv + condaで仮想環境を作る

condaを使ってパッケージのインストールなどを行うため、面倒な依存関係のものも比較的簡単にインストールできる。特に分析系のパッケージは依存関係が面倒なものが多いので、こちらが楽かもしれない。(ごちゃごちゃ知らないものがインストールされるのが嫌だ!という人は、上記の pyenv+virtualenvで1つずつ自分でインストールする方が良さそう。)

pyenv install -lでみつけた anaconda3系の環境をインストールする

$ pyenv install anaconda3-5.1.0

$ pyenv global anaconda3-5.1.0 でインストールした環境に切り替える。

  system (set by /Users/ysdyt/.pyenv/version)
  3.6.5
  3.6.5/envs/test
* anaconda3-5.1.0

condaで仮想環境を作る

$ conda create -n test2 python=3.6.5 opencv

ここでは test2が任意の環境名、python=3.6.5がインストールしたいpythonのバージョン、opencvがインストールしたいパッケージ。パッケージはスペース区切りで複数書いてもok

pyenv versionsで確認して、環境の一覧に入っていればok

  system (set by /Users/ysdyt/.pyenv/version)
  3.6.5
  3.6.5/envs/test
* anaconda3-5.1.0
  anaconda3-5.1.0/envs/test2

condaで作った環境に切り替える。

$ pyenv global anaconda3-5.1.0/envs/test2

pyenv versions して、以下になっていればok

  system (set by /Users/ysdyt/.pyenv/version)
  3.6.5
  3.6.5/envs/test
  anaconda3-5.1.0
* anaconda3-5.1.0/envs/test2

condaの仮想環境も削除する場合は pyenv uninstallする

$ pyenv uninstall anaconda3-5.1.0/envs/test2

condaでのパッケージインストールは
$ conda install hogehogeでも$ pip install hogehogeでもどちらでもok

(余談)

condaで作成した環境には pyenv global test2以外にも conda activate test2でも切り替えることができる。その場合、プロンプトの先頭に (test2) という文字列が追加されて、現在どこの環境にいるのか明示してくれる。

しかし、ややこしいことに、condaの環境に入った状態で pyenv vesionsしても現在いるconda環境に * がつかない。

condaの場合、conda env list をすると現在どのcondaの仮想環境にいるのかを * 付きで教えてくれる。

なんだか面倒なので、pyenvでもcondaでも有効な pyenv globalで環境の切り替えを行えば良いと思う。
(もしかするとなにか間違ってるかもしれません...)

参考