Pythonに限った話ではないですが、プログラミングをしていると、使っているライブラリのバージョンを変えたいけど別のライブラリとの依存関係があって難しい…みたいなことってありますよね。
こういったバージョン由来のトラブルやつらみをある程度カバーして助けてくれるのが、仮想環境とパッケージ管理です。
仮想環境とパッケージ管理を使いこなせるようになれば、少なくとも「バージョンの依存関係であっちを入れたらこっちが動かなくなった!」とか「Pythonのバージョンを上げたらこっちのパッケージが動かなくなった!」みたいなトラブルからは解放されます。
今回はPython初心者向けに、仮想環境とは何ぞという話と、venvとpipを使った標準的なPythonにおけるパッケージ管理方法、さらにPipenvを使ってもう少し楽に管理する方法などについて書いていきます。
■venvとpipを使ってみる
Pythonで開発をしていると、使おうと思ってpip installしたライブラリが固定のバージョンにしか対応していないとか、このシステムでは古いバージョンを使いたいけど、また別の開発では最新版を使いたい…というように、バージョンに翻弄されてしまうことがよくあります。
そこで、固定のバージョンやライブラリ類が使える閉じた環境(=仮想環境)を使います。
この仮想環境をパッケージ管理しようと思ったら、仮想環境のツールに付随して特定のバージョンで固定しておく…といった方法が多いかと思います。単純にpipでrequirements.txtを用意しておくのが、最も単純なやり方ですね。
特に仮想環境を使ったりパッケージ管理したりしていない場合は
pip freeze > requirements.txt
で入っているライブラリ類を全て出力することができます。
出力されるファイルはそれぞれの環境で異なるかと思いますが、たとえば
numpy==1.14.2 opencv-contrib-python==3.4.0.12 opencv-python==3.4.0.12 pandas==0.19.2 pandocfilters==1.4.1 pdf2image==0.1.10 pexpect==4.2.1 pickleshare==0.7.4 Pillow==5.0.0
みたいな感じで出てきます。numpy==1.14.2というのはnumpyのバージョン1.14.2が入ってますよ~という意味です。
このtrequirements.txtを別の環境へ持っていって
pip install -r requirements.txt
とするだけで、requirements.txtのライブラリがまるっとインストールされます。便利ですな。
ただ、複数のプログラムを取り扱っていると「今回はあのライブラリは必要ない」とか「あのライブラリだけバージョンを変えたい」といった感じで、環境を分けたいなあというケースが増えてきます。
そこで仮想環境の出番です。
まずは、Python3で推奨されているvenvを使ってみましょう。
python3 -m venv test_python
とすると、 test_pythonという仮想環境が作られます。できた仮想環境に入ってみましょう。
source test_python/bin/activate
とコマンドを打てば、仮想環境に入れて、 (test_python) とターミナルの頭に付くようになるかと思います。
仮想環境から抜けるには
deactivate
と打ちます。
仮想環境が本当にちゃんと分離しているのか確認するために、もう一つ仮想環境を作ってみましょう。
python3 -m venv test_python_sub
これで、test_python と test_python_sub という2つの仮想環境ができました。
それぞれがちゃんと分離しているのか確認してみましょう。
source test_python/bin/activate pip install flask pip freeze > test_python_requirements.txt deactivate source test_python_sub/bin/activate pip install bottle pip freeze > test_python_sub_requirements.txt deactivate cat test_python_requirements.txt
とすると、出力は
click==6.7 Flask==1.0.2 itsdangerous==0.24 Jinja2==2.10 MarkupSafe==1.0 Werkzeug==0.14.1
となり、pip installでflaskを入れたことや、その依存関係がtest_python_requirements.txt に書き出されます。
cat test_python_sub_requirements.txt
とすると、出力されるのは
bottle==0.12.13
だけです。bottleは依存関係がないので、単独でインストールされています。
このようにすれば、 source */bin/activate 〜 deactivate で環境を分離できて、不要なライブラリやバージョンの不一致などによるトラブルを避けられます。
またvenvを使うと、OS標準で使っているPythonから隔離した状態でもパッケージ管理ができます。
仮想環境の取り扱いについて、詳細は以下の公式ドキュメントに書かれています。
28.3. venv --- 仮想環境の作成 — Python 3.6.6 ドキュメント
公式的には、venvで仮想環境を作り、pipでいい感じにパッケージ管理しましょう…ということが推奨されています。
■Pipenvを使ってみる
venvとpipだけでもよいのですが、それだけだとかゆいところに手が届かない場合もあるなぁということで、今回はPipenvも試してみます。
Pipenv: 人間のためのPython開発ワークフロー — pipenv 2018.7.1 ドキュメント
人間のためのPython開発ワークフロー…というだけあって、venv・pipだけだと管理しきれない部分もフォローしてくれます。
pip install pipenv
で入ります。
mkdir pipenv_test cd pipenv_test pipenv install
とすると、Pipenvの仮想環境や設定ファイルが吐き出されます。
pipenv shell
で、venvのsource */bin/activate と同じように仮想環境のシェルに入ることができます。
Pipenvでパッケージ管理をする場合は、pipではなくpipenvでパッケージのインストールを行います。
pipenv install flask
とすると、Pipfile.lock(requirements.txtと同じようなもの)には
[packages] flask = "*"
が追記されます。バージョン指定が無いので "*" となっていますが、バージョン指定しても大丈夫です。
Pipfile.lockには
"default": { "click": { "hashes": [ "sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d", "sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b" ], "version": "==6.7" }, "flask": { "hashes": [ "sha256:2271c0070dbcb5275fad4a82e29f23ab92682dc45f9dfbc22c02ba9b9322ce48", "sha256:a080b744b7e345ccfcbc77954861cb05b3c63786e93f2b3875e0913d44b43f05" ], "index": "pypi", "version": "==1.0.2" },
というように、依存関係のあるパッケージのバージョンやハッシュ値などが管理されています。
Pipfileと同様に、別の場所でPipfile.lockを使ってパッケージをインストールして使うこともできます。
ちなみにPipfileをただ別の場所に持っていって pipenv install とすると、 Pipfile から各種パッケージとPythonの仮想環境がインストールされて、さらにPipenvで指定されたバージョン(指定されていなければ最新版)を固定したPipfile.lockが作られます。
pipenv installでPipfileを無視してPipfile.lockのみを参照してパッケージをインストールしたいとき(要するにバージョン固定したいとき)には、 --ignore-pipfile オプションをつけることで実行できます。
あと、普通の requirements.txt がほしい場合は(あまりないかと思いますが、pipenvを使っていない環境に同じバージョン入れたい時とか)
pipenv lock -r
とするとpip freezeと同じ結果が得られます。pipenv shellなどで入るとpip freezeでも同じ結果が得られますが。
また、pipenvではPythonのバージョン管理もできます。
pipenv --python 3.6.2
とすると、Pipfileに
[requires] python_version = "3.6"
というふうに、3.6のバージョン指定ができます。
ここで、たとえば先日出た3.7を指定してみたい~というときは、 "3.6" を "3.7" に書き換えて
pipenv --rm pipenv install
とすれば、Pythonのバージョンが切り替わった仮想環境になります。
また、pipenvには pipenv check というコマンドがあり、PEP 508に従っているかどうかとsafetyを使った脆弱性のチェックをしてくれます。
公式ドキュメントに例が出ていますが、たとえば django = "==1.10.1" というふうにDjangoの脆弱性があるバージョンを指定していると、pipenv checkしたときに脆弱性が見つかったぞという警告などを表示してくれます。
Pipenvの進んだ使い方 — pipenv 2018.7.1 ドキュメント
あとは、pipenv graph とすると依存関係をこんなふうにいい感じに表示してくれたりします。
Flask==1.0.2 - click [required: >=5.1, installed: 6.7] - itsdangerous [required: >=0.24, installed: 0.24] - Jinja2 [required: >=2.10, installed: 2.10] - MarkupSafe [required: >=0.23, installed: 1.0] - Werkzeug [required: >=0.14, installed: 0.14.1] pandas==0.23.1 - numpy [required: >=1.9.0, installed: 1.14.5] - python-dateutil [required: >=2.5.0, installed: 2.7.3] - six [required: >=1.5, installed: 1.11.0] - pytz [required: >=2011k, installed: 2018.5] scipy==1.1.0 - numpy [required: >=1.8.2, installed: 1.14.5]
たとえばPandasとScipyはNumpyを参照しているんだな、といったことがひと目で分かって便利です。
■まとめ
というわけで、Pythonの仮想環境&バージョン管理に関する初歩的な話でした。
最近Pythonを使うようになったばかり…という人は、とりあえず公式推奨の venv + pip を使うのがいい気がする…。
ほかにもPythonや機械学習などに関する記事をいろいろ書いているので、興味のある方は見てみてください。
paiza.hatenablog.com
paiza.hatenablog.com
「まずはPythonでプログラミングできるようになりたい!」という方は、プログラミングが動画で学べる「paizaラーニング」の「Python入門編」(今年から全編無料になりました)から始めてみてください。先日新しく「Python入門編7: 関数を理解しよう」が追加されました。
「paizaラーニング」では、未経験者でもブラウザさえあれば、今すぐプログラミングの基礎が動画で学べるレッスンを多数公開しております。
詳しくはこちら
そしてpaizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。
スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキルを客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。
詳しくはこちら