pyenvが必要かどうかフローチャート

pyspaの統合思念体の渋川です。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">「pyenv使いましょう！」系の記事、全部ゴミ</p>&mdash; Yoshifumi YAMAGUCHI (@ymotongpoo) <a href="https://twitter.com/ymotongpoo/status/781408616456736768">September 29, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

これはpyenvがダメではなくて、pyenvをとりあえずインストールしておきましょう記事がダメという意味だそうです。すでに[とんぷーが5年前にこの問題について書いています](https://plus.google.com/+YoshifumiYamaguchi/posts/aPgWC3B7Wrg)。これを読んで分かる人には不要です。

**この記事では「便利」と「必要」は分けて考えています。後者にフォーカスしています。**

前提知識
==========

Environment Isolation Tool(環境分離ツール)というカテゴリの開発補助ツールがあります。pip install Sphinxとか書いたら、ライブラリはグローバル空間に入っちゃいます。複数バージョン入れられません。そんなときに使うのが、この環境分離ツールです。最近はいろいろな言語がこれを提供しています。

あとは、処理系をたくさんいれて選択できるツールがあります。SwitcherとかSelectorみたいな名前でもあったりします。

virtualenv/venv
--------------------

環境分離ツールです。このような仕組みを整備した普及させた第一人者ですし、2008年に出版されたExpert Python Programmingですでにベストプラクティスとして書かれています。Python 3.3ではvenvという名前で取り込まれたので、Python界では元祖にして今後の主流となることが確定しています。venvはWindowsでも動きます。

環境分離ツールですが、ライブラリ名前空間を分けるだけではなく、virtualenvはPythonの処理系のバージョンも設定できます。ただし、venvは、実行したツールのバージョンしかまだ対応してないらしく、今後3.4、3.5以降が一般化してきたら(3.3はpipが標準化される前なので微妙なので置いといて)・・・なのかな。

venv/virtualenvはPythonのデファクトスタンダードなので、各種ツールのサポートが充実しているのが強みになります。JetBrains社のPython IDEのPyCharmは、プロジェクトごとの環境設定で環境の選択ができますし、venvでプロジェクト以下に環境作ってからPyCharmで開くと、選ばなくてもデフォルトでvenv環境使ってくれるそうです。

![pycharm01.jpg](https://qiita-image-store.s3.amazonaws.com/0/6105/bcdffa7e-d90b-9767-e46d-fe56d7570b76.jpeg)

PyCharmはPythonコードを解析して補完をだしてくれるため、ただしく使用しているライブラリを教えてあげることがコーディングを楽にしてくれます。

![Pasted image at 2017_01_13 09_35 AM.png](https://qiita-image-store.s3.amazonaws.com/0/6105/6d5bcce1-0912-5826-4afe-33cdf7adab3c.png)

Visual Studio CodeのPythonエクステンションもワークスペース以下のvenvを見つけてくれます。

pyenv
--------------------

pyenvは後者のツールです。バージョン指定して処理系をとってきて共存させられる、というのがコア。

* Linux環境だと、Pythonは2系/3系の2つしかパッケージでは入れられない。古いパッケージを無理やり入れると、依存関係で古いのを持ってこようとして破滅するのでこれはやらない方が良い
* Mac/Windowsでも、バイナリをパッケージマネージャとか標準インストーラで入れると、マイナーバージョン違いは共存できるけど、パッチバージョンでの共存はできない。pyenvならできる。

バージョン切り替えだとpythonzというツールもあります。それ以外だとpythonbrewもありましたが、pythonbrewのREADMEには、もう積極的にメンテしてないからpyenv使えと書かれています。知らなかった。

virtualenvにはできず、pyenvにしか提供できないものというのは、たくさんのバージョンの処理系を入れることができるという点ですね。他にはpythonz、deadsnakeがあります。

[ちなみに日本ではQiita等で良く見かけますが、世界的にはこんな感じです。](https://public.tableau.com/views/Virtualenvvs_Pyenv/Dashboard?:embed=y&:display_count=yes)
virtualenvのほうが圧倒的に使われているようです。

Anaconda
--------------------

最近、データ分析界隈で人気のツールです。なんでもデータ分析に使えるライブラリとかツールをまるっと抱え込んでいるそうです。名前をよく聞くようになってきたので、昨日インストールしてみました。

消しました。

Anacondaの/binをパスに設定するのですが、Anacondaがなかで持っているツール(openssl/curl/python)がOSの持っているツールを覆い隠してしまいます。あと、BASH前提になりすぎてて、zsh使ってると色々直さないと動きません。ちょっとこれはPythonを普段使っている人には影響がでかすぎる。もちろん、Windowsならバッティングするものはないので、問題ないと思います。

もちろん、Anacondaの有用性自体が否定されるものではありません。便利だと思います。なにより、virtualenv機能が内蔵されていて、Pythonバージョンを指定して(2.7, 3.4, 3.5対応)環境を作ったり、環境に必要なパッケージをGUIで選択してインストールしたりできる。これは便利です。

issueはとりあえず上げましたが・・・・こいつはやっかいですね。有能な愚者は無能な愚者よりも厄介といいますが、便利でユーザ数が増えているのにこれというのは・・・

**2017/9/3追記**

WindowsユーザーがAnacondaを使わざるを得ない理由の一つとして、SciPyというライブラリがありました。8月に[リリース計画の発表](https://mail.python.org/pipermail/scipy-dev/2017-August/022050.html)があり、1.0からはWindowsバイナリのwheelもPyPIで提供されることが発表されました。

* Sep 16: Branch 1.0.x
* Sep 17: beta1
* Sep 27: rc1
* Oct 7: rc2
* Oct 17: final release

これで、素のPythonで言語の標準的なプロセス（pip）でできないことが少し減ります。

pyenvがもたらすネガティブな側面
============================

良くわからないまま、チュートリアル記事に書かれているのに従ってpyenvをインストールしたという初心者がハマるケースがよく観測されています。Pythonの講習会、ボランティアでやっているハンズオンその他(PythonとかSphinxとか)ではまって、解消に時間がかかると。

そもそも、習う必要があるというのは、Pythonとか周辺に不慣れだから習うわけで、トラブルシューティングもままならないケースが多いです。本人だけではなく、周りの時間を奪うことになります。

pyenvが一般ユーザにあまり必要がない理由
====================================

pyenvはRubyの文化から来ていますが、そもそもPythonでは処理系のバージョンをあげろ圧力はあまりないです。周りのツールが揃うまではバージョンを上げないで待つ、というのも行われてきたことです。ライブラリも、少し前のバージョンまでサポートするのはよく使うのは当たり前。ライブラリがバージョンアップしたら、Pythonのサポートバージョンが古い方に伸びた、というのも見かけたことがあります。OSがシステムコンポーネントとして使っているのがPython。RedHatの古いバージョンだと未だに2.4バンドルですよね。さすがにライブラリで2.4を積極的にメンテはない(2.6以上じゃないと3系と同時メンテはツライ)ので、そこまで古いバージョンでは古いライブラリ使ってね、とはなりますが。

Pythonの3系の移行の話が話題になりますが、古いバージョンを使い続けるのが問題というよりも、3系にライブラリが対応してないから、3系に上げたくても上げられないという縛りが問題です。2.7も2020年まではサポートされるのは明記されているわけですし。ただ、他の人のアップデートを邪魔するのはいかんよ、と。とはいえ、3系も出てきてしばらく経つし、そろそろ新バージョンは3系のみ、というライブラリも出てくるようです。3.5は非同期I/Oも入ったし、古いコードを落としてダイエットしつつ先に行こうという流れは活発化すると思います。

RubyもRailsを使わなければバージョン上げる圧力はそんなにないと聞きます。パフォーマンスが上がるから「使いたい」、はあっても「バージョン上げないと死ぬ」はないと。Ruby以上にアップデート圧力とバージョン固定が大事になっているのがnode.jsですよね。

pyenvにしかできないものもあるにはありますが、Pythonを普段から仕事でバリバリ書いてる！みたいな人でなければ、LinuxやMacだったらシステムのPythonをそのまま or MacPorts/Homebrewで入れたPythonをそのまま使っちゃえば良いです。必要になるまで最適化しちゃいけないって言いますよね。環境分ける必要が出てくる(複数のサービスを面倒見る必要が出てくる)まではいらないです。

ツールの組み合わせ
=================

Pythonはなるべくミニマムでやるべし、暗黙でいろいろやる便利ツールよりは、明確な意図を持って選ぶべきという文化です。執筆時点の現状で、Pythonicな選択肢はこんなものかと思います。

ウェブサービスのガチ開発者
------------------------

pyenvではなくて、今ならDockerとかvagrantとかを使って、コンテナ化/仮想化の方が良いと思います。Pythonのバージョンだけじゃなくて、データベースのバージョンとか、周りのミドルウェアとか、OSのバージョンとか、サービスごとに要件はいろいろあるはずですし。

ライブラリの開発者
---------------------

ライブラリはさまざまなバージョンから使われます。そのため、これらのバージョンをインストールして使う必要があります。

Rubyは1系の時はRubyのマイナーバージョン==一般のメジャーバージョン、Rubyのパッチバージョン=一般のマイナーバージョン、Rubyのパッチ番号==一般のパッチバージョン的なところはあったと思いますが、2系になってたぶん普通になったと思います。PythonもRuby2系と(たぶん)同じく、マイナーバージョンレベルの先頭でさえテストしておけば基本的にOKなのでこれで十分。逆にnode.jsはメジャーバージョンが一般のマイナーバージョンの勢いですが。

下記でtoxについて紹介していますが、toxは内部でvirtualenvの環境を一時的に作ってテストする、ということをします。virtualenvは使っているけど環境をわざわざ作る必要はなく、travis.ciのマトリックステストをローカルでやっているようなものです。

* [toxで、PythonとDjangoのバージョンでマトリックスバージョンテストの例](https://github.com/tokibito/django-ftpserver/blob/master/tox.ini)

### Linux

Linuxだと、複数バージョンのPythonの共存は普通にはできないので、pyenvを使い、バージョンごとの環境を作ってテストしてくれるtoxを使えば良いです。ただし、複数バージョン入れるのも「Linux の場合、ぶっちゃけ configure && make && make install が十分だし、必要以上にスタック増やすなよ」という意見も少数ではなかったです。

### Mac/Windows

MacとWindowsだったらtoxだけでもOKだと思います。python.orgで配布しているインストーラで入れれば複数バージョン入れられます。

ライブラリのガチ開発者/QA担当
----------------------------

当然パッチバージョンまでそろえてテストする必要があるので、pyenv/toxになると思います。

Mac/LinuxのAnacondaユーザ
-------------------------

システムのPATHを上書きしてOSのコンポーネントをシャドーイングしちゃうという凶悪仕様により、マジメに対応するならpyenvしかなさそうです。AnacondaのサイトのFAQを見ても、PATH環境変数芸でハックしろとかしか書かれてなくて、これはひどい。

その他
-------

Windowsはシステムのツールとバッティングすることもないはずなので、Anacondaをそのまま入れてあげれば良いと思います。BASHがなくても環境アイソレーションツールとして使え、パッケージも入れられる。pyvenvを待たずに2.7でも環境分けができます。

ただし、Windowsでも他のインストーラでPythonを入れていると、Anacondaがそれを隠してしまって問題が極めて発見しにくい事象が発生するようです。Pythonはさまざまなツールと一緒にインストールされることがあるので要注意です。pyenvは動かないと思うので、パスを直さないとダメだと思います。

それ以外でも、カジュアルにPythonを本を読みながら勉強するぞ、ウェブサービス作ってみるぞなら2.7か3.5の最新だけ入れてそれだけで動かしていても問題ありません。

チャート
---------

上記のものは用途ごとのチャートです。使う条件によるチャートは以下の通りです。ちょっと字は小さいですが、拡大してみてみてください。

<img width="1174" alt="スクリーンショット 2016-10-01 23.11.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/6105/7e49d95d-7642-0944-f07b-74843d813710.png">

結論
=====

環境設定で「pyenv」「pyenv」と書かれている人に知っておいて欲しいことは2つ

* 処理系のバージョン指定はvirtualenvでもできるしpyenvのpython-buildでインストールだけすれば十分。virtualenv(pyvenv)が今後の標準。レールに乗ろう。
* PythonにRailsはない。繰り返す。PythonにRailsはない。Pythonはnode.jsでもない。

あった方が仕事が捗る人はいますが、必ずしもそうではないですし、慣れない人ほど落とし穴にハマる点が、「とりあえずpyenv」「pyenvを必要のない人に進める記事」は滅ぶべき(O氏談)と言われるポイントです。仕事が捗る、便利だと思う人は自己の責任で。決定版とかみんな使うべきとか大きい主語はやめましょう。

pyenv便利という話は周りからいくつか出てきたのですが、Pythonダウンロードツールとしては使っているけど、環境切り替えとしては使ってない人ばかりでした。

```
ダウンロード＋CMMI の自動化＋若干の有用なパッチ = python-build

shims という仕組みを使ったバージョン切り替えは要らないけど、 python-build 
を使って、 ~/pyenv/versions/3.x.y だけ用意したいというとき「pyenv 
を使って Python をビルドしてるけど shims は使ってない」という人も
「pyenv使ってる」「pyenv便利」にカウントされる
```

python-buildが切り出されれば、喜んで使う人は増えるんじゃないかなと思いました。

感想見ていると、他の環境とツールが揃っているから云々というのを見かけたのですが、もちろんそれは最初から否定はしていません。最初に書いたとおり、便利だと思って、自分のユースケースを見て必要性が判断できて、何をやっているか理解して使う分には本人の自由です。「他の言語環境を知っている」というのはPythonは初心者かもしれないけど、特殊な初心者だと思います。あくまでも、本記事の趣旨は、「Pythonを初めてみるけど、Python良くわからないし、なるべくトラブル無くスタートしたい」という人に対する落とし穴を減らすのが目的です。

あと、一番悪いのはAnacondaです。みんなissueをあげましょう。