584
505

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

pyenv、pyenv-virtualenv、venv、Anaconda、Pipenv。私はPipenvを使う。

Last updated at Posted at 2019-03-29

はじめに

If a thing can be done adequately by means of one, it is superfluous to do it by means of several; for we observe that nature does not employ two instruments if one suffices.
-- Thomas Aquinas (1225-1274)

pyenv-virtualenv というツールを、私は長らく使ってきた。
pyenv-virtualenvは素晴らしいツールで、私はプロジェクトを切り替えるとき、Pythonの環境について一切悩むことなくただcdするだけでよかったし、他の環境で作業するときも、requirements.txtを通じて全く問題なく環境をコピーすることができていた。
私の.zshrcには、「Pyenv-virtualenvがなければ勝手にgit cloneしてパスを通し、pyenv-initを実行する」という処理が堂々と鎮座していた。

しかし、時代は変わった。
Pipenvを試したとき、私の中でpyenv-virtualenvは終わりを迎えた。
Pyenvは私にとってブルドーザーだったし、pyenv-virtualenvは私にとって時間喰い虫だったのだ。

今日はまだpyenv-virtualenvに囚われている亡霊のあなたに向けて、Pipenvへの転生の門を開こうと思う。

Pythonを取り巻く、環境戦国時代

この記事を読むために、まずはPythonにおける環境構築手法をいくつか知っておかねばならないだろう。

Pythonインタプリタには、様々なバージョンがある。もしあなたが考古学者なら、Python2系の存在を知っていることだろう。3系の中でも互換性のない変更はたくさん行われているし、あるいはPyPyIronPythonといった(よく知られた)Pythonとは異なる実装のインタプリタもある。
つまり、我々はたくさんのPythonを持っていて、それらをプロジェクトに応じて適切に切り替えなければならない。

また、Pythonには様々なパッケージがある。開発者はこれらを好き勝手にインストールして使うわけだが、もちろんこれらのパッケージにもバージョンや互換性の問題は存在する。「このプロジェクトは、このパッケージをインストールしないと動きません。ただし、バージョンxx以上yy以下です。」という注意書きがすべてのプロジェクトに存在しており、それらをうまく扱うためにはパッケージのバージョンを切り替えてくれるツールが当然必要だ。

そういうわけで、我々は2つのものごとについて仮想環境を必要としている。
すなわち、Pythonインタプリタ本体と、パッケージ群である。

まとめ

インタプリタ切替 パッケージ切替 パッケージインストール
pyenv
virtualenv
pip
venv
pyenv-virtualenv
virtualenvwrapper
Anaconda
Pipenv

pyenv

pyenvは、前述した2つのうち前者のみを担当する仮想環境マネージャである。

pyenvのやることは以下の通りである:

  • $PATHの先頭にPYENV/shimsを挿入し、あらゆるPython系コマンドへのアクセスに割り込む。
  • いま動かすべきPythonインタプリタを探す。
  • 受け取ったコマンド(例えばpython main.pypip3 install -r)を、その探したインタプリタに投げる。

すなわち、諸々のコマンドを適切な窓口に振り分ける、受付係を引き受けてくれるのである。

適切なインタプリタを探すために、pyenvは以下の操作を行う:

  • もし環境変数PYTHON_VERSIONが設定されていれば、そのバージョンに従う。
  • そうでなければ、今のディレクトリから順に親ディレクトリを遡っていく。その途中で.python_versionファイルが見つかれば、そこに書かれているバージョンに従う。
  • ルートまで遡っても見つからなければ、グローバルに設定されているバージョンに従う。

こうすることで、今いるプロジェクトにとって最も適切なPythonを起動することができるのである。

結局、Pyenvを用いる利点は以下の通り:

  • 状況に応じて適切なPythonインタプリタを、手動で切り替えることなく用いられる。
  • いろいろなPythonインタプリタを、コマンド一発でインストール・アンインストールできる。

virtualenv

virtualenvは、前述した2つの両方、すなわちPythonインタプリタとパッケージ群を同時に切り替えられる仮想環境マネージャである。

virtualenvは、ENV/以下にPythonインタプリタ、インストールされたパッケージなどすべてを保存している。そして、source ENV/bin/activateを行うと(これがvirtualenvを使うための魔法の呪文である)、その仮想環境のフォルダにパスが通る。これ以上のことは何もしない。

いちいち仮想環境の場所を探してactivateしなければならないという面倒臭さはあるものの、動作は単純明快であり、環境が分離されていることもわかりやすい。ただし、pyenvとは異なり、新しいPythonをインストールしたりはできないので注意が必要である。あくまでも$PATHを探してPythonを見つけ、そのインタプリタをコピーするだけである。

結局、virtualenvを用いる利点は以下の通りである:

  • Pythonインタプリタとパッケージの組み合わせを好きなだけ作り、分離することができる。
  • それらをactivateで切り替えることができる。

pip

pipは、Python公式のパッケージ管理ツールである。

Pythonを知っている人であれば、この並びにpipが居るのはおかしいと思うかもしれない。
実際、pipPythonインタプリタを切り替えてはくれないし、パッケージの仮想環境を作ってくれるわけでもない。

pipがすることは、Pythonのパッケージを探し、適切なバージョンのパッケージを、依存関係を解決しながらインストールすることである。
venvpyenv-virtualenvなど、多くの仮想環境ツールはpipを使ってパッケージをインストールすることを想定している。

pipでインストールしたパッケージは、requirements.txtという形で共有することができる。
このrequirements.txtには、必要に駆られてインストールしたパッケージのほか、依存関係の解決に必要だったパッケージ、開発時に必要だったlinterパッケージなどもすべて記述されている。
別の環境でそのプロジェクトを実行したければ、適当な仮想環境の下でpip install -r requirements.txtとすれば、それらのパッケージが全てインストールされ、元と同じ環境で実行できるというわけだ。

ここでpipを紹介した理由は、もちろん、このあとpipの仕事を代替するツールが登場するからである。

pyenv-virtualenv

pyenv-virtualenvは、pyenvのシステムに乗っかりつつ、virtualenvを用いることができるツールである。
pyenvともvirtualenvとも別物である点に注意されたい。

pyenv-virtualenvでは、pyenvと同様のインターフェースでvirtualenvを用いることができる。しかも、pyenvのように、状況に応じて適切な仮想環境を、手動で切り替えることなく用いることができる。

すなわち、virtualenvでは

~$ cd project1  # Projectに移動
~/project1$ python -V
python 2.7.10  # まだ切り替わっていない
~/project1$ source ~/.virtualenv/project1/bin/activate  # 仮想環境をアクティベート
~/project1 (project1)$ python -V
python 3.7.3  # 切り替わった

というような処理を踏んでいたのが、

~$ cd project1  # Projectに移動
~/project1 (project1)$ python -V
python 3.7.3  # もう切り替わった
~/project1 (project1)$ ls -a
. .. .python_version  # .python_version に仮想環境の名前が書かれている

と、cdするだけで仮想環境の切り替えが済んでいるのである。

でも、どうやって?

実は、pyenv-virtualenvは、あらゆるコマンドのあとにactivateのチェックを行っている。
先述した、「今のディレクトリから順に親ディレクトリを遡っていく。その途中で.python_versionファイルが見つかれば、そこに書かれているバージョンに従う。」を、すべてのコマンドのあとに行っているのである。
当然、あらゆるコマンドの実行速度は目に見えて低下する。
activationの手間を省くために、かなりのコストを支払っているのである。

結局、pyenv-virtualenvを用いる利点は以下の通りである:

  • pyenvと同じインターフェースで、virtualenvを用いることができる。
  • virtualenvで用いるPythonに、pyenvでインストールしたpythonを用いることができる。
  • virtualenvactivateによるバージョンの切り替えを、手動で切り替えることなく用いられる。

venv (旧称: pyvenv)

venvは、Python公式が提供する仮想環境マネージャである。
その挙動はvirtualenvとあまり変わらない。

公式が提供しているのだし、virtualenvを生で使うくらいならこっちを使うのがいいのではないだろうか。

virtualenvwrapper

virtualenvwrapperは、何かと使い勝手の悪いvirtualenvの動作を隠蔽し、変なことをしないようにするラッパーである。
使ったことがないのであんまりわからないが、おとなしくvenvを使っておけばいいと思う。

Anaconda (, miniconda, conda)

Anacondaは、Pythonインタプリタのインストールから仮想環境の作成、パッケージのインストール、その他の環境構築などなど、Pythonに纏わるあらゆることをすべて一手に引き受けるスーパーブルドーザーである。
あらゆることを引き受けるので、ここで述べているようなインタプリタのインストールや切り替え、パッケージの切り替えなども当然引き受けてくれる。

もちろん、Anacondaには、pipを代替する機能もある。例えばpipではpip install mypyとするところ、condaではconda install mypyなどとすることでmypyパッケージをインストールすることができる。
また、このパッケージ管理システムとPythonインタプリタだけを備えた最小限のAnacondaが、minicondaとして配布されている。

Anacondaを使うなら、Pythonに関するあらゆることはすべてAnacondaに任せてしまうという気持ちが必要だ。
Anacondaの担当範囲があまりにも大きすぎて、他のどんな仮想環境ツールとも競合してしまうからである。
特に、Anacondaのパッケージ管理がpipと異なることで、「ほしいパッケージのバージョンがcondaにない! でもいまさらpipは使えない……」ということが結構あったりするのだ。その点は注意しなければならない。

何にせよ、どこまでがAnacondaの支配領域なのかを明確に理解できるようになるまでは、Anacondaを使うべきではない、と個人的には思う次第だ。

Pipenv

Pipenvは、virtualenvの仕事に加えて、Pipfileという次世代のパッケージ管理システムを実装したツールである。
Pipenvは仮想環境を作成するだけでなく、pipと同じようにパッケージ管理を行うことができる。その際、pipとは異なり、「何が要求されたパッケージで、何が依存関係の解決に必要だったパッケージなのか」を記録することができる。
これによって、どのパッケージがどのパッケージによって要求され、どのパッケージによってバージョン固定されたのかがわかり、パッケージリストがきれいになるのである。

Pythonに馴染みがない人にとっては、あまり利点がわからないかもしれない。
実際、あまり開発をしないのであれば、venvで十分なのではないかという気もする。

あと、これは個人的な主観なのだが、インターフェースが非常にわかりやすい。
新しいプロジェクトで仮想環境を作りたければpipenv installとするだけ、git cloneしてきたプロジェクトに置いてあったPipfileを読み込むときもpipenv installとするだけ、pipの代わりに使うときもpipenv install <package-name>pippipenvに置き換えるだけ。大変わかりやすい。

まとめ

インタプリタ切替 パッケージ切替 パッケージインストール
pyenv
virtualenv
pip
venv
pyenv-virtualenv
virtualenvwrapper
Anaconda
Pipenv

pyenv-virtualenvをやめ、Pipenvを使う

以上の仮想環境ツールを比較した上で、私はpyenv-virtualenvをやめ、Pipenvを使うことにした。

pyenv-virtualenvをやめたことで、私のshellは爆速になった。もう二度とpyenv-virtualenvを使うつもりはない。

Pipenvはあくまでも仮想環境マネージャなので、Python自体のインストールは別の方法で行う必要がある。
pyenvに任せてもいいのだが(実際、Pipenvにはpyenvと協調する仕組みがある)、pyenvのやってくれることのうち「状況に応じて適切なPythonインタプリタを用いられる」という部分はPipenvがすでに担当しており、仕事が被ってしまうと思ったので、Pythonは手動でインストールすることにした。

実際、普通の人間に必要なPythonは最新バージョンのstableなpython(現時点では3.7.3)だけであり、あとは時々3.6や3.5、考古学者のために2.7が必要になるくらいである。Pyenvのような強いシステムの出る幕はたぶんない。

Pipenvのインストールは単純で、公式ページに書かれている通り、brewaptで入れたり、あるいはpython -m pip install --user pipenvとするだけである。

新しくプロジェクトを立ち上げる際には、

~$ mkdir project1  # Projectを作成
~$ cd project1  # Projectに移動
~/project1$ pipenv install  # 仮想環境を作成
~/project1$ pipenv shell  # 仮想環境に入る

とすればよい。
次からは単にpipenv shellとするだけである。

おわりに

この記事では、pyenvvirtualenvpipvenvpyenv-virtualenvvirtualenvwrapperAnacondaPipenvを並べ、それらの特性について軽くまとめた。
この記事が皆さんのPythonライフの一助となれば幸いである。

Pipenv流行れ。

584
505
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
584
505

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?