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の仮想環境を作る場合、主に`vertualenv`や`conda 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`で環境の切り替えを行えば良いと思う。
（もしかするとなにか間違ってるかもしれません...）



## 参考

- [pyenv/pyenv-virtualenv/Anacondaを使ってクリーンなPython環境をセットアップ](https://karaage.hatenadiary.jp/entry/2016/04/04/073000)
- Special Thanks [@keisuke-nakata](https://qiita.com/keisuke-nakata)