dondakeshimoの丸太

データサイエンス/Webアプリケーション/

Pythonの環境構築奮闘記 あるいは降参記

モチベーション

Pythonは最高だ! コードの見た目は綺麗で,3rdパーティモジュールも豊富, 何よりもiPython kernelの存在が大きいと思う. もっというとJupyterだ. あるいばHydrogen(Atom package)だ. ブラウザでもお好きなブラウザでもコードを書きながら即時実行できる強みは計り知れない.

しかし,Pythonの環境構築周辺はとっちらかっている. 議論もベストプラクティスもハゲ散らかっている. Pythonの環境構築について思い悩んだ挙句, 一旦思考をまとめるのと思考の記録を残す目的で本ログを残す. (注: ほぼポエム)

現状の考察

環境構築ツール

下記サイトなど色々なサイトでまとめられているため,まとめのまとめレベルで記述する.

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

Pythonバージョン切り替え パッケージ切り替え
pyenv
pyenv-virtualenv
venv
virtualenv
pipenv
anaconda
docker

必要事項

  • Pythonバージョンの使い分け
  • Python仮想環境の独立性
  • Python仮想環境の再現性及び手軽さ
  • 開発環境のストレスフリー

ここでPython仮想環境とはvirtual envやpipenvで作成した環境を指す.

Pythonバージョンの使い分け

絶対に必要がどうかは疑わしいという議論もある. しかし,導入自体はツールさえインストールしてしまえば簡単にでき, tensorflowなどのPythonバージョンに依存するモジュール(知識が古かったらすみません) も容易に使えるようになることや, 実行環境のPythonバージョンが固定されている時のことなども考えると あって損はない機能というか,やっぱり必要機能だと感じる.

Python仮想環境の独立性

これはどこまで仮想環境を切り分けるかという話である. 例えば,pyenvのみを用いた場合はバージョン毎の切り分けは可能だが, プロジェクト単位での環境の切り分けはできない. しかし,プロジェクトの依存関係がはっきりしないプロジェクトというのは, 個人開発の域を出た瞬間になんとも言えない不安感を煽る. イケてないと感じるし,イケてない人だと苦笑いされるのは最悪の気分だ.

Python仮想環境の再現性及び手軽さ

上述の独立性を担保する上で,留意しておきたい点がこの二つである. 独立性を担保し,依存関係がはっきりしていることは非常に好ましいが, さらにその仮想環境を違うマシン,環境でも簡単にサクッと再現できる必要がある. 著者は古くからの requirements.txt はとても好きだ. Simple is best だ. 逆に自分にとって手軽だろうが,自前のシェルスクリプトなどは再現性が下がるので論外となる.

開発環境のストレスフリー

ざっくり分けて環境には2種類あり, それぞれ開発環境と実行環境に分けられる. ここで議論している環境は実行環境を大きく意識した開発環境を整えることである. しかし,実行環境のために開発環境の便利さをトレードオフさせることは避けたい,いやだ,ありえない.

欲しい環境のまとめ

実行環境を意識した上で,バージョンと依存関係がプロジェクト単位で独立しており, その仮想環境を他の環境でも容易に再構築できるが, それら全ては開発環境の機能を損なうものであってはならない.

ベストプラクティスの考察

  • Atom(+ Hydrogen)が好きです
  • pipenv, venv, virtualenv, pyenv-virtualenv だとやはり...
  • anacondaに委ねる
  • docker等,上位の仮想環境で戦う
  • pyenv + pyenv-virtualenv はやっぱりありでは
  • pyenv + pipenv は次世代みがある

Atom(+ Hydrogen)が好きです(ポエム強め)

いきなり個人の趣向が入ってきて,ベストプラクティス(笑)になってしまった. Atom + HydrogenはAtomエディタ上でiPythonを用い, 各行実行や,セクション実行が可能なプラグインである. 布教が目的とかではないけど是非使ってみてほしい.惚れると思う.

さて,このプラグインを実行するためにはJupyter環境が必要になるのだが,これが曲者である. Jupyter入れるだけでしまいやん!とはならない. 上記の必要事項にプロジェクト毎の独立性と書いたが, その要件を満たした場合,Hydrogenの実行カーネルを それぞれのプロジェクトに対して変更する必要がある. ...だが,無理だ. そのような機能は,ない. 管理手法がそれぞれ異なるのにそのような出すぎた要求はできない.

そのため,筆者はどのプロジェクトでも使える共通の,なんでも入りの仮想環境を一つ作り, そのカーネルをHydrogenに登録して用いている. どう考えても,実行環境と開発環境に乖離が生じているためダメだろうという構成である. 仮想環境は最後にその構成で動くかどうか確認し,他人と共有する為のものと化してしまっている.

Jupyterで開発している人もどうしているのだろうか. 全てのプロジェクトにJupyter入れているんだろうか?

Hydrogenを諦めればなんでも綺麗にまとまる気がしてきた. しかし,必要事項の開発環境のストレスフリーに反する為, 結局筆者はこのような環境を現状使い続けるだろう. Hydrogenのカーネルを仮想環境毎に割り振るツールでも作れば良いのだろうが... あれ,それで解決するのでは? 来週の予定,埋まりました.

pipenv, venv, virtualenv, pyenv-vritualenv だとやはり...

pipenv,ナウいんだろう,知らんけど.

という所感を環境構築のリサーチ中に受けた. これら4つはPythonのバージョン管理は機能として持っておらず, Python仮想環境の構築にのみ特化したものである. 基本的な機能はどれも同じで,少し前までのデファクトがvirtualenv, 最近評価をあげているのがpipenvという印象である. 正直どれでも良い気もするし,venvには触ったことがないしおすすめ出てこないしで一旦スルーする.

pipenvはnpm(JavaScriptの似たような機能のやつ)などの影響を受けているらしい? 必要パッケージだけでなくその依存モジュールまで記録してくれる. npmのようにその環境独自のコマンドを用意することもできる. 最も後発で,機能としては最も完璧に近いと思う. ただ,遅い.依存関係の記録が異常に遅い.ついでに毎回最初に pipenv run つけるの面倒くさい. pipenv shell はわかりづらい.

virtualenvやpyenv-virtualenvは再現性がpipenvと比べて低い. pipenvでは pipenv install の1コマンドで済むところを それぞれの開発者がrequests.txtに応じて開発環境を構築することが必要となる. 逆に開発者それぞれにpipenvの依存関係が軽減されるということでもある. pyenv-virtualenvの方が手軽だが, 多数のプロジェクトを抱える場合,環境の中央集中の一括管理であるため取っ散らかる. virtualenvはactivateするのが面倒だったり,環境の使い回しができないデメリットがある.

やはり...とかなかった. 一長一短だった. 最初はpipenvに落ち着けるつもりだったけど, 書き始めたらむしろ愚痴の方が出てきたため保留.

anacondaに委ねる

anacondaは全部やってくれる. マジで全部.本当に全部.全然全部. 以前はWindows環境の場合,その他のツールが動かないため, anaconda以外の選択肢がなかったし, 実際これさえあればかなりほぼ全ての要求に答えることができる. じゃあ,これでええやん!とならないのがややこしいところである.

anacondaそのものの是非について

Anacondaの利用は是か非か?(またはそれでも私がAnacondaを“今“使う理由) - DEVGRU

この辺に議論が書いてある. 多分批判点(メリット)をざっくりまとめると

  • 権限周りの危険が危ない説がある
  • 大量のパッケージを入れられて容量とかうざい(大量のパッケージ美味しい)
  • pipと競合する(condaの方が楽にインストールできるものも存在する(した))

この辺に突っ込むと長くなりそうだし,完全に把握しているわけではないからこの辺で飛ばす. 現状,anacondaを使うなら全てをanacondaに委ねる覚悟が必要そう. 何かと共存させるのはどうなんだろうという状態らしい. 筆者はpyenvでanacondaをインストールして使っていたが, これは大量のパッケージが事前に入っていて便利だったからである. その程度の理由ならとっととanacondaから撤退した方が吉だろうと思い,全部捨てた.

docker等,上位の仮想環境で戦う

docker最高!Vagrandとかでも全然あり! 速度のオーバーヘッドはあまりないし,ここまで仮想化したら実行環境への意識という点では完璧だ. ...だが,弊環境では難しい. 一つ大きな理由がマシンの容量が怖いところである. メインマシンがストレージ256GBのMacなのが全部悪い. もう一つ運用できないため実際にぶち当たったことはないのだが, 開発環境でストレスが出るのではないかという懸念もある. できればAtomで開発したいのだが,この場合ボリュームを結合するか, 何かの都度書いたスクリプトをdocker環境にコピーする必要がある. jupyterサーバを立てる手もあるため, そこで下書きをしながらスクリプトを書いてコピーという流れが良いのだろうか. マシンをアップグレードすれば非常に興味のある構成なので是非ご教授願いたい.

pyenv + pyenv-virtualenv はやっぱりありでは

筆者が最近環境を再考するまで使用していた構成である. そしてこの投稿を書きながら,Hydrogenを使うに最も適当な構成であると気づき. 再度この構成に落ち着かんとしている. 問題としては環境の再現性が大きいと思うし, 実際のところpipenvの方がイケてる感は否めないので他人に勧めるようなものでもない.

pyenv + pipenv は次世代みがある

目下ネット上の第一おすすめ候補だろう. かっこいいし,いいと思う. 遅い問題については --skip lock オプションをつけることで大きく軽減されるらしい. それでもどこかのタイミングでlockせざるを得ないが. この問題についてはpipenvの開発者も認識しているらしく,近い将来改善されることが期待される. もう一つの仮想環境に入るの面倒あるいわかりづらい問題は, 自分のターミナルを適応させることでなんとかなると思う. というかそういうの考えるのは割と好き.

まとめ

  • 開発環境さえ整えばdockerが最高!(と思う)
  • パッケージ管理特化のツールはpipenvが一つ抜けている気もするが,(まだ)五十歩百歩
  • anacondaは好き嫌い分かれてる
  • 開発環境を完璧に整えるのはdockerに限らず難しい