この際だからAnacondaやらpyenvやらPython仮想環境をいろいろ試してみた

これは[NTTドコモ R＆D Advent Calendar 2020](https://qiita.com/advent-calendar/2020/nttdocomo)の18日目の記事です。

# はじめに

こんにちは。ドコモ社員の石川です。

僕はいつもデータ分析とかをしていて、特に機械学習とかでPythonをよくいじったりしているんですが、気がついたら使用していた仮想環境がごちゃごちゃになっていたのでこれを機会に一度整理してみようと思いました。

ちなみに整理する前の僕の環境は、まずpyenvが導入されていて、その１つの仮想環境にanaconda3.6を立ててある感じで、つまり仮想環境の中に仮想環境が入っていてる感じですね。

しかも特に環境を切り替えることもあまりなく、このように入り組んだ構築をしたにもかかわらず全くその意味を成していない状態でした。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491658/efded7ec-dee4-0968-498a-62782e27b27f.png)

まあ特に問題なく動いてくれているのでこのままでも良いかな〜とも思っていたのですが、「**もしかして無駄に動作が重くなってる？**」「**新しいPythonバージョン使いたいけど環境新しく立てるのめんどいな？**」と思ったのをきっかけに整理してみようと思いました。

そこで今回はいろいろある仮想環境を実際に試してみて、それぞれどんな特徴があったのかまとめてみようと思います。
みなさんのより良いPython開発環境の構築に参考になれればと思います。

なお、本記事中の実行環境はDocker上で動作しているUbuntu:20.04になります。
文中の実行コマンドを参考にされる際は適宜`sudo`で実行してください。

また記事の最後に「[こういう人にはこの環境がおすすめ](https://qiita.com/dcm_ishikawa/private/beabdb488f0636cf95fc#%E7%B7%8F%E8%A9%95%E3%81%93%E3%82%93%E3%81%AA%E4%BA%BA%E3%81%AF%E3%81%93%E3%81%AE%E4%BB%AE%E6%83%B3%E7%92%B0%E5%A2%83%E4%BD%BF%E3%81%8A%E3%81%86)」というのをまとめたので、そちらを先にご覧になっても良いかなとも思います。

今回はこちらの記事「[pyenv、pyenv-virtualenv、venv、Anaconda、Pipenv。私はPipenvを使う。](https://qiita.com/KRiver1/items/c1788e616b77a9bad4dd)」を参考にさせていただきました。


# 仮想環境の種類

今回試したのは下の７種類です。

- pyenv
- virtualenv
- pyenv-virtualenv
- venv
- Anaconda
- 素のPython
- Pipenv

# pyenv

pyenvでできることは、

- 各Pythonバージョンのインストール
- Pythonのバージョンの切り替え
- 特定のディレクトリ配下で利用するバージョンの自動切り替え

とのことです。


```bash:pyenvの導入
apt install -y \
build-essential \
libffi-dev \
libssl-dev \
zlib1g-dev \
liblzma-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
git \
wget

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 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc
```

```bash:インストールできるPythonの一覧
pyenv install --list
```

```bash:Python3.9.0をンストール
pyenv install 3.9.0
```

```bash:デフォルトのPythonを3.9.0に指定
pyenv global 3.9.0
```

```bash:pythonの実行
python
```

```bash:numpyのインストール
pip install numpy
```

参考：[ubuntu 20.04 / 18.04 に pyenv をインストールする話](https://qiita.com/neruoneru/items/1107bcdca7fa43de673d)

## pyenvの所感

### 長所

- 非常にシンプル。
- 新しいバージョンのPythonを簡単にインストール、切り替えができる。
- pipの導入も勝手にやってくれるので簡単にPythonを導入できる。

### 短所

- `.bashrc`を書き換えてまでいるのにそこまで機能がないので人によっては好き嫌いあるかも。
- 同一のPythonバージョン内でパッケージ環境の分離、切り替えができない。

# virtualenv

virtualenvでできることは、

- Pythonのバージョンとパッケージ環境の切り替え

になります。Python自体のインストールは別途必要になります。


```bash:virtualenvの導入
apt install virtualenv
```

```bash:仮想環境の作成
# 任意の場所に'test_env'の名前で環境の保存場所を作成
mkdir ~/test_env
# 仮想環境の保存場所として指定
virtualenv ~/test_env                       # この場合マシンのデフォルトのPythonバージョンが使われる
virtualenv -p /usr/bin/python3.9 ~/test_env # バージョンを指定したいときはインストール済みのものをこんな感じで指定する
```

```bash:仮想環境の起動
. ~/test_env/bin/activate
```

```bash:pythonの実行
python
```

```bash:numpyのインストール
pip install numpy
```

```bash:仮想環境の停止
deactivate
```

```bash:仮想環境の削除
rm ~/test_env -r
```

参考：[Virtualenvインストールとセッティングする方法(Ubuntu)](https://codechacha.com/ja/virtual-env-setup/)

## virtualenvの所感

### 長所

- 同一のPythonバージョン内でパッケージ環境の切り替えができる。
- 他のパッケージ管理ができるものと比べて気持ち軽量

### 短所

- virtualenvを使って新しくPythonをインストールできない。
- 仮想環境の起動、停止、切り替えでいちいちコマンドを打たなければならないので面倒。

# pyenv-virtualenv

そもそもpyenv-virtualenvは、pyenvのプラグインだそうです。

機能としてはpyenvのものに加えて

- Pythonのバージョンとパッケージ環境の切り替え
- 特定のディレクトリ配下で利用するPythonのバージョンとパッケージ環境の自動切り替え

とのことです。


```bash:pyenv-virtualenvの導入
# pyenvがインストール済みの状態で
git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv
eval "$(pyenv virtualenv-init -)" >> ~/.bashrc
source ~/.bashrc
```

```bash:仮想環境の作成
# Python3.9.0で'test_env'の名前で環境を作成（pyenvでPython3.9.0をあらかじめインストール済み）
pyenv virtualenv 3.9.0 test_env
```

```bash:仮想環境の起動
pyenv global test_env
```

```bash:pythonの実行
python
```

```bash:numpyのインストール
pip install numpy
```

```bash:仮想環境の停止
source deactivate
```

```bash:仮想環境の削除
pyenv uninstall test_env
```

参考：[Ubuntuへのpyenv-virtualenvのインストールと使い方をまとめておく。他のディストリビューションでもいけると思う](https://note.com/kaoricrowd/n/n0d31f7d5fa4f)

## pyenv-virtualenvの所感

### 長所

- 新しいバージョンのPythonを簡単にインストールができてる。
- 同一のPythonバージョン内でパッケージ環境の切り替えができる。
- 仮想環境の作成がシンプル。
- 仮想環境の起動、停止、切り替えでいちいちコマンドを打たなければならないが、pyenv同様に特定のディレクトリに特定の仮想環境を割り当てて自動切り替えさせることができる。

### 短所

- 全てのコマンドを実行する際に後ろで1回1回環境チェックが走るので動作が重くなる。
- `.bashrc`を結構書き換える必要あり。

# venv

venvの特徴は、virtualenvとほぼ同じでした。

ただ、各Pythonバージョンをインストールする方法がそもそもvenvをインストールするのと同義なのでよりシンプルな感じです。


```bash:venvの導入
# 今回は3.9で仮想環境を作ります。
apt install python3.9-venv python3-pip
```

```bash:仮想環境の作成
# 'test_env'の名前で環境を作成
python3.9 -m venv ~/test_env
```

```bash:仮想環境の起動
source ~/test_env/bin/activate
```

```bash:pythonの実行
python
```

```bash:numpyのインストール
pip install numpy
```

```bash:仮想環境の停止
deactivate
```

```bash:仮想環境の削除
rm ~/test_env -r
```

参考：[UbuntuにPython3.8とvenvの仮想環境をインストールする](https://www.suzu6.net/posts/236-install-python3-at-ubuntu/)

## venvの所感

- virtualenvとほぼ同じ。
- 公式が提供しているものなので安心して使える。

# Anaconda

Anacondaでできることは、

- 各Pythonのバージョンのインストール
- パッケージ環境の管理
- パッケージのインストール（`pip`の代わりに`conda`コマンドでできる）

とのことです。


```bash:Miniconda(Anacondaの軽量版)の導入
cd ~
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
chmod 777 Miniconda3-latest-Linux-x86_64.sh
~/Miniconda3-latest-Linux-x86_64.sh
source ~/.bashrc
```

```bash:仮想環境の作成
# Python3.8.0で’test_env’の名前で仮想環境を作成
conda create -n test_env python=3.8.0
```

```bash:仮想環境の起動
conda activate test_env
```

```bash:pythonの実行
python
```

```bash:numpyのインストール
# condaコマンドでできる。
# pipコマンドでもできるが衝突しないようにどちらかに統一して使った方が良さそう。
conda install numpy
```

```bash:仮想環境の停止
conda deactivate
```

```bash:仮想環境の削除
conda remove -n test_env --all
```

参考：[minicondaのインストールと仮想環境の複製・インポート](https://qiita.com/Gushi_maru/items/be7b5124a382e699e79d)

## Anacondaの所感

### 長所

- Pythonのインストール、パッケージ環境管理、パッケージのインストール全部やってくれて初心者に優しい。
- Anacondaが全部請け負ってくれるので管理が楽。

### 短所

- ホームディレクトリにいろいろ保存される。
- 仮想環境の起動、停止、切り替えでいちいちコマンドを打たなければならないので面倒。
- `conda`コマンドが重く感じる。
- [一部利用制限あり](https://www.anaconda.com/blog/sustaining-our-stewardship-of-the-open-source-data-science-community)

# 素のPython

ここで言う"素のPython"とは、

- `apt install`で各Pythonバージョンをインストールする
- パッケージ環境の管理はしない
- Pythonのバージョンは実行時にコマンドで指定する

という非常に原始的な方法です。


```bash:Python3.9のインストール
apt install python3.9
apt install python3-pip
pip3 install -U pip
```

```bash:pythonの実行
python3.9
```

```bash:numpyのインストール
python3.9 -m pip install numpy
```

## 素のPythonの所感

### 長所

- インストールするものが最小限。最も軽量。

### 短所

- インストールがやや複雑
- もちろんパッケージ環境の管理はできない。
- 実行コマンドや、pipコマンドが複雑。ただし、下記のようにaliasを指定しておけば他のと同じように`python`や`pip`コマンドで実行できるようになる。

```bash
echo "alias python=\"python3.9\"" >> ~/.bashrc
echo "alias pip=\"python3.9 -m pip\"" >> ~/.bashrc
source ~/.bashrc
```

# Pipenv

Pipenvとは、

- Python自体とは独立していて、もちろんPythonのインストール機能はない
- `pip`の代わりにパッケージのインストールができて、同時にパッケージ環境の管理までする

というものです。

```bash:Pipenvのインストール
apt install python3-pip python3-distutils python3-dev
pip3 install --upgrade setuptools
pip3 install pipenv
echo "export PIPENV_VENV_IN_PROJECT=true" >> ~/.bashrc
source ~/.bashrc
```

```bash:仮想環境の作成
# aptでPython3.9をインストールし、’~/test_env'にPython3.9の仮想環境を作成
apt install python3.9
mkdir ~/test_env
cd ~/test_env
pipenv --python 3.9
# pyenvをインストールしておくと、このときに未インストールのバージョンの場合インストールも一緒にしてくれるそうです。
```

```bash:numpyのインストール(仮想環境を起動していないとき)
pipenv install numpy
```

```bash:仮想環境を起動
pipenv shell
```

```bash:numpyのインストール(仮想環境を起動中のとき)
pipenv install numpy
# または
pip install numpy
```

```bash:Pythonの実行
python
```

```bash:仮想環境を停止
exit
```

```bash:仮想環境を削除
pipenv --rm
```


参考：[【Ubuntu 18.04】pyenv+pipenvでPython環境構築](https://qiita.com/fury00812/items/08036e78a449d1cbeb48)、[Ubuntu 20.04にpipenvとmoviepyをインストールする](http://serverarekore.blogspot.com/2020/08/ubuntu-2004pipenvmoviepy.html)

## Pipenvの所感

### 長所

- 仮想環境ごとにインストールしてあるパッケージとそのバージョンの一覧が簡単にわかる。

```text:~/test_env/Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
numpy = "*"

[dev-packages]

[requires]
python_version = "3.9"
```

### 短所

- `pipenv install`コマンドが重い。
- 仮想環境の作成、起動、停止が面倒。


# 総評（こんな人はこの仮想環境使おう）

今回7種類の仮想環境を試してきましたが、実際に使ってみてこう言う人向けにはこれが向いているな？と思ったものをまとめてみました。

これから環境構築する人や、見直したい人にご参考にしていただければと思います。

* **パッケージ管理の必要がなく**滅多にPythonの**バージョンも変えない**、apt等を用いたインストールに慣れている。
    * 素のPython

* **パッケージ管理の必要がない**がPython **バージョンは切り替えたい** 、新しくしていきたい。とにかく**手っ取り早くシンプルかつ簡単に**Python環境構築したい。
    * pyenv

* **パッケージ管理が必要**で、**面倒くさくない**切り替えがしたい
    * pyenv + pyenv-virtualenv

* **パッケージ管理が必要**で、コマンドが**重くなるのは嫌だ**
    * venv

* 共同でコーディングしていて**みんながPipenv使っている**、または**パッケージ管理をスマートに**したい
    * pyenv + Pipenv

* 上記以外、または**Python周りを全部まとめてよろしくして欲しい**
    * Anaconda


# 反省と戒め

ここからは余談ですが、今回の執筆を経て学んだことを書いておきます。

今回の調査をしていて途中で思ったことがありまして、「**そもそも僕、Dokcer使ってるんだからPythonの仮想環境いらないじゃん**」です。pyenvやAnacondaを使う必要がないのにコンテナの中にゴリゴリにインストールだけしていた感じですね。pyenvやAnacondaにはそれぞれ特有の素晴らしい機能や良さがあるにも関わらず、それらを全く使わずに動作だけを遅くしていたと言う渋い状況でした。

みなさんもPython環境に限らず自分がいつも使っているもの、自分がおかれている環境の特性をよく理解しながら仕事や研究をしていますか？一度立ち止まってそれらと改めて正面から向き合い、それらの持っている本来の特性を捉えることでみなさんのパフォーマンスを最大限に発揮できるようになるかもしれません。

この記事によって一人でも多くの人の仕事や研究での活動、Python環境がより良くなることを願っています。