pipenvとpyenvによる複数の独立したPython仮想開発環境の管理
複数の開発プロジェクトが手元にあり、プロジェクトAはpython3.7、プロジェクトBはpython3.6を必要とし、プロジェクトAとプロジェクトBが互いに独立し、干渉しないことが求められるといった開発要件によく遭遇します。このような開発ニーズに対応するためには、複数のバージョンのPythonを自分のPCにインストールし、プロジェクト間で環境を分離する必要があります。複数のバージョンのPythonをインストールするには、pyenvという良いツールがあり、複数のプロジェクト間で隔離された開発環境を作るには、pipenvというさらに良いパッケージ管理ツールがあります。
この記事では、pyenvとpipenvを使用してpythonの開発環境を管理する方法について、核となる2つの事柄に焦点を当てながら概要を説明します。
- 同じコンピュータで複数のバージョンのPythonを管理する方法。
- プロジェクトごとに、互いに隔離された仮想環境を作成する。
01 - 複数のバージョンのPythonをインストールする
自分たちで開発したり、githubからクローンした複数のプロジェクトは、異なるPythonインタープリタに依存している場合があります。そのため、これらのプロジェクトを実行するには、作業用のコンピュータに異なるバージョンのPythonをインストールする必要があります。
pyenvはPythonのバージョン管理ツールで、同じコンピュータに複数のバージョンのPythonを簡単にインストールすることができます。
1.1. pyenv のインストールまたはアップグレード
まずpyenvをインストールします。もしあなたがMacを使っているならば、Homebrewをインストールするのがおすすめです。
$ brew update && brew install pyenv
pyenvのアップグレードを行うには、次に実行します。
$ brew update && brew upgrade pyenv
Macでない場合は、githubの方法を使ってインストールしてください。
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
$ exec "$SHELL"
このインストールに関する詳細な説明は、やはり公式ドキュメント https://github.com/pyenv/pyenv#basic-github-checkout を参照することをお勧めします。
github でインストールした pyenv の場合、以下の手順でアップグレードできます。
$ cd $(pyenv root)
$ git fetch
$ git tag
v1.2.18
$ git checkout v1.2.18
pyenv がインストールされたら、$(pyenv root)/shims を PATH 変数の先頭に追加する必要がありますが、これは重要なステップです。
$ echo 'export PATH="$(pyenv root)/shims:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
1.2. pyenvを使ったPythonのインストール
pyenvをインストールした後、Pythonをインストールすることができます。
$ pyenv install 3.7.7
$ pyenv rehash
pyenv versions コマンドを実行し、インストール結果を確認します。
$ pyenv versions
system
* 3.7.7 (set by /Users/chunming.liu/.pyenv/version)
ご覧の通り、Python 3.7.7 が /Users/chunming.liu/.pyenv に正常にインストールされました。
1.3. Pythonのバージョン切り替え
Python のバージョンは pyenv global または pyenv local で切り替えることができます。pyenv global はグローバルな切り替えで、一度切り替えを行うと、システム内のどこで python を実行しても同じバージョンの Python を見つけることができます。
$ pyenv global 3.7.7
$ pyenv versions
system
* 3.7.7 (set by /Users/chunming.liu/.pyenv/version)
3.7.7の前にアスタリスクがついているのがわかりますが、これは3.7.7への切り替えに成功したことを意味しますので、pythonを実行して確認してみてください。
$ python
Python 3.7.7 (default, Apr 12 2020, 12:31:11)
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
pyenv local はローカルスイッチで、カレントディレクトリの Python のバージョンだけを変更し、カレントディレクトリの外では無効です。
次に、プロジェクトごとに個別の開発環境の構築を開始します。
02 - Pipenvで仮想環境を作る
Pipenvは、Pythonの公式推奨パッケージ管理ツールです。virtualenv、pip、pyenvの機能を兼ね備えています。pipenvは、インストール、アンインストール、依存関係の追跡、ログ取得、および仮想環境の作成、使用、整理のためのツールとして使用することができます。
2.1. pipenv のインストールとアップグレード
Mac を使用している場合、Homebrew を使用して pipenv をインストールおよびアップグレードすることをお勧めします。
$ brew update && brew install pipenv
$ brew update && brew upgrade pipenv
Pipenvはpipでインストール、アップグレードすることも可能です。
$ pip install pipenv
$ pip install --upgrade pipenv
2.2. プロジェクト用の仮想環境の作成
プロジェクトディレクトリに移動し、以下のコマンドでプロジェクト用の仮想環境を作成します。
$ mkdir pipenv_demo
$ cd pipenv_demo
$ pipenv --python 3.7.7
Creating a virtualenv for this project...
Pipfile: /Users/chunming.liu/work/pipenv_demo/Pipfile
Using /Users/chunming.liu/.pyenv/versions/3.7.7/bin/python3 (3.7.7) to create virtualenv...
⠙ Creating virtual environment... .Using base prefix '/Users/chunming.liu/.pyenv/versions/3.7.7'
New python executable in /Users/chunming.liu/.local/share/virtualenvs/pipenv_demo-RYMSREda/bin/python3
Also creating executable in /Users/chunming.liu/.local/share/virtualenvs/pipenv_demo-RYMSREda/bin/python
Installing setuptools, pip, wheel... done.
done.
Running virtualenv with interpreter /Users/chunming.liu/.pyenv/versions/3.7.7/bin/python3
✔ Successfully created virtual environment!
Virtualenv location: /Users/chunming.liu/.local/share/virtualenvs/pipenv_demo-RYMSREda
上記のアクションは、pipenv_demo プロジェクト用に Python 3.7.7 の仮想環境を初期化し、プロジェクトエントリの下にプロジェクト依存パッケージファイル Pipefile を生成します。システム上に Python 3.7.7 のバージョンがない場合、pipenv は pyenv を呼び出して対応するバージョンの Python をインストールします。
デフォルトでは、仮想環境は ~/.local/share/virtualenvs ディレクトリの中に作成されます。また、pipenv --venvでプロジェクトの仮想環境ディレクトリを表示することができます。仮想環境は、pipenv --rm で削除することができます。
仮想環境のディレクトリを変更したい場合は、.bashrc や .bash_profile に環境変数 WORKON_HOME を設定して、仮想環境のディレクトリの場所を指定します。例えば、仮想環境を ~/.venvs ディレクトリに置きたい場合は、以下のコマンドを実行してください。
$ echo 'export WORKON_HOME=~/.venvs' >> ~/.bash_profile
$ source ~/.bash_profile
プロジェクト・ディレクトリに仮想環境ディレクトリ (.venv) を作成する場合は、.bashrc または .bash_profile で環境変数 PIPENV_VENV_IN_PROJECT を設定することが必要です。
$ echo 'export PIPENV_VENV_IN_PROJECT=1' >> ~/.bash_profile
$ source ~/.bash_profile
03 - Pipenvによる依存パッケージの管理
pipenv は依存パッケージの管理に Pipfile と Pipfile.lock を使用し、pipenv でパッケージを追加または削除する際に Pipfile ファイルを自動的に保守し、インストールしたパッケージのバージョンと依存情報をロックするために Pipfile.lock を生成します。これは、pip が手動で requirements.txt にインストーラとバージョンを維持する必要があったことに比べて、大幅な改善となります。
3.1 依存性パッケージのインストール
プロジェクトの依存パッケージを仮想環境にインストールし、各プロジェクトが独立した依存パッケージを持つようにすることは、Python開発の良いプラクティスです。依存パッケージを仮想環境にインストールするには、以下のようにします。
$ pipenv install pytest
Installing pytest...
Adding pytest to Pipfile's [packages]...
✔ Installation Succeeded
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
✔ Success!
Updated Pipfile.lock (1c4d3d)!
Installing dependencies from Pipfile.lock (1c4d3d)...
???? ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 11/11 - 00:00:16
To activate this project's virtualenv, run the pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
上記のコマンドを実行した後、インストールが成功したかどうかを確認します。
$ pipenv graph
pytest==5.4.1
- attrs [required: >=17.4.0, installed: 19.3.0]
- importlib-metadata [required: >=0.12, installed: 1.6.0]
- zipp [required: >=0.5, installed: 3.1.0]
- more-itertools [required: >=4.0.0, installed: 8.2.0]
- packaging [required: Any, installed: 20.3]
- pyparsing [required: >=2.0.2, installed: 2.4.7]
- six [required: Any, installed: 1.14.0]
- pluggy [required: >=0.12,<1.0, installed: 0.13.1]
- importlib-metadata [required: >=0.12, installed: 1.6.0]
- zipp [required: >=0.5, installed: 3.1.0]
- py [required: >=1.5.0, installed: 1.8.1]
- wcwidth [required: Any, installed: 0.1.9]
pytestがすでにインストールされていることがわかり、またpytestの依存パッケージもリストアップされています。
プロジェクトのルートを見ると、さらにPipfile.lockというファイルがあります。このプロジェクトの依存パッケージを記録したこれら二つのファイルの違いは、Pipfile にインストールされたパッケージにはパッケージ固有のバージョン番号が含まれていないのに対し、Pipfile.lock にはパッケージ固有のバージョン番号が含まれていることです。Pipfile.lock ファイルを生成したくない場合は、依存パッケージのインストール時に -skip-lock オプションを追加すればよいでしょう。
依存関係パッケージファイル Pipefile を開くと python_version = "3.7" とあり、このプロジェクトが Python バージョン 3.7 をベースにしていることがわかります。パッケージセクションには、bpytest = "* "としてプロジェクトの依存パッケージがリストアップされ、アスタリスクは最新バージョンを表しています。
$ cat Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]]
[packages]
pytest = "*"
[requires]
python_version = "3.7"
そして、Pipfile.lockには、インストールされた依存パッケージの具体的なバージョン番号が記載されています。このインストールされた pytest はバージョン 5.4.1 であり、その依存パッケージのバージョンが記載されていることがわかります。
$ cat Pipfile.lock
{
"_meta": {
"hash": {
"sha256": "828b8ad012f4c8773e6e61e3ac2be0ffcd7540fd7ed175a8355676c8e31c4d3d"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.7"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"attrs": {
"hashes": [
"sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c",
"sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"
],
"version": "==19.3.0"
},
"importlib-metadata": {
"hashes": [
"sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f",
"sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e"
],
"markers": "python_version < '3.8'",
"version": "==1.6.0"
},
"more-itertools": {
"hashes": [
"sha256:5dd8bcf33e5f9513ffa06d5ad33d78f31e1931ac9a18f33d37e77a180d393a7c",
"sha256:b1ddb932186d8a6ac451e1d95844b382f55e12686d51ca0c68b6f61f2ab7a507"
],
"version": "==8.2.0"
},
"packaging": {
"hashes": [
"sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3",
"sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752"
],
"version": "==20.3"
},
"pluggy": {
"hashes": [
"sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0",
"sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"
],
"version": "==0.13.1"
},
"py": {
"hashes": [
"sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa",
"sha256:c20fdd83a5dbc0af9efd622bee9a5564e278f6380fffcacc43ba6f43db2813b0"
],
"version": "==1.8.1"
},
"pyparsing": {
"hashes": [
"sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
"sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
],
"version": "==2.4.7"
},
"pytest": {
"hashes": [
"sha256:0e5b30f5cb04e887b91b1ee519fa3d890495f428c1db76e73bd7f17b09b172",
"sha256:84dde37075b8805f3d1f392cc47e38a0e59518fb46a431cfdaf7cf1ce805f970"
],
"index": "pypi",
"version": "==5.4.1"
},
"six": {
"hashes": [
&
3.2 依存性パッケージのインストール速度の改善
pipenvを使用する場合、インストールに時間がかかることがあります。vパラメータを追加することで、インストールプロセスのステップの情報を見ることができ、ダウンロードのところで引っかかることがあります。pipenvで作成されるPipfileのデフォルトのPypiソースは、公式のpythonソース.org/simpleです。国内のユーザーの方はダウンロードに時間がかかると思います。
Pypiの国内ミラー経由で依存関係をインストールしたい場合は、パッケージのインストール時に-pypi-mirrorを指定します。例えば、清華大学のミラー経由でflaskパッケージをインストールするには
$ pipenv install --pypi-mirror https://pypi.tuna.tsinghua.edu.cn/simple flask
毎回 --pypi-mirror を指定する必要がないように、私は通常、Pipfile を作成した後、ファイルの source ブロックの下の url フィールドを、以下のように国内の pypi ソース(私は清華の Pypi ソースか Ali のソースを推奨)に設定するようにしています。
[[source]]
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
verify_ssl = true
name = "pypi"
3.3 依存パッケージの削除
仮想環境からサードパーティ製パッケージを削除する場合は、以下のコマンドを実行します。
$ pipenv uninstall pytest
3.4 プロジェクトの依存パッケージをすべてインストールする
gitでプロジェクトを管理する場合、バージョン管理にPipfileとPipfile.lockを追加してください。こうすることで、プロジェクトのクローンを作成した学生は、そのクローンに対して
$ pipenv install
pipfile の [packages] セクションに記載されているすべてのパッケージをインストールし、コンピュータ上にプロジェクト用の仮想環境を自動的に作成します。
3.5 pipefile.lockに依存性パッケージをインストールする
上記の方法はすべて、Pipfile に記載されているサードパーティ製パッケージの最新版をインストールするものです。Pipfile.lock にあるサードパーティの依存パッケージの固定バージョンをインストールしたい場合は、実行する必要があります。
$ pipenv install --ignore-pipfile
3.6 requirements.txt 内の依存関係パッケージのインストール
プロジェクトが以前にrequirements.txtを使用して依存関係を管理していた場合、pipenvを使用してすべての依存関係をインストールすることは、pipと同様の方法で行うことができます。
$ pipenv install -r requirements.txt
04 - 仮想環境での開発
仮想環境を作成したら、その中で開発することができます。
コマンドラインから開発する場合は、プロジェクトディレクトリでpipenvシェルを実行して仮想環境に入ると、すでにインストールされているすべての依存関係が含まれ、その上で作業を行うことができます。
$ pipenv shell
Launching subshell in virtual environment...
bash-3.2$ . /Users/chunming.liu/.local/share/virtualenvs/pipenv_demo-RYMSREda/bin/activate
(pipenv_demo) bash-3.2$ python
Python 3.7.7 (default, Apr 12 2020, 12:31:11)
[clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pytest
>>>
Pycharmで開発している場合、Pycharmで直接プロジェクトを開くとさらに簡単です。Pycharmの左側のナビゲーションバーにExternal Librariesがあり、仮想環境のPythonインタプリタが表示されています。
開発したプログラムを仮想環境で実行するには、前述のpipenv shellを実行してからpythonプログラムを実行する方法と、pyenv runを実行する方法があります。例えば、pytestフレームワークに基づくテストケースを仮想環境で実行するには、以下のコマンドを実行するだけでよいのです。
$ pipenv run py.test
04 - 概要
この記事では、pyenvを使用して複数のバージョンのPythonをインストールする方法と、異なるPythonのバージョン間で切り替える方法を紹介しました。また、Pythonの公式推奨パッケージ管理ツールであるpipenvを紹介しました。pipenvとvirtualenvの長所を組み合わせて、プロジェクトの仮想環境の管理や、プロジェクトの依存パッケージの管理に役立てることができます。
pyenvとpipenvを試してみることを強くお勧めします。実際には、バージョン管理には virtual-environment.venv ではなく Pipfile と Pipfile.lock を追加することをお勧めします。このパッケージはサイズが大きく、pipenv install の方法でリビルドすることができます。プロジェクトの項目ごとに別の仮想環境を作り、プロジェクトごとにPipfileを使って依存関係を管理するのは非常に良い習慣です。
参考文献
https://github.com/pyenv/pyenv
https://github.com/pypa/pipenv
https://packaging.python.org/tutorials/managing-dependencies/#installing-pipenv
https://hackersandslackers.com/pipenv-python-environment-management/
最新の記事については、公開番号:"Ming says software testing"をフォローしてください。
関連
-
PythonでクロールするときにAttributeError: 'NoneType' オブジェクトに 'find_all' 属性がないのを解決する
-
undefinedImportError: 必要な依存関係['Numpy']がありません。
-
Python_matplotlib の凡例は外側に保存すると不完全になる
-
Error: cannot run program--createprocess error=2,The system cannot find specified file.
-
SyntaxError: 構文が無効です。
-
ImportError: torchvision という名前のモジュールがありません。
-
AttributeError: 'function' オブジェクトに 'split' 属性がない Solution
-
プログラム実行中にPythonの例外が発生しました。TypeError: 'NoneType' オブジェクトは呼び出し可能ではありません。
-
Pycharmの未解決の参照問題
-
Mac環境でのbrewコマンドが見つからないエラーの解決方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[Python] error could not broadcast input array from shape (26) into shape (26,1)
-
ImportError: Windows の Django でプロジェクトを作成するとき、django.core solution という名前のモジュールがない。
-
ORMにおけるトランザクションとロック、Ajaxによる非同期リクエストと部分リフレッシュ、Ajaxによるファイルアップロード、日時指定Json、マルチテーブルクエリブックのシステム
-
python マルチスレッド操作エラー。logger "websocket "のハンドラが見つかりませんでした。
-
Python による pyserial 経由でのシリアルポートの読み取りと書き込み
-
Pythonモジュールの簡単な説明(とても詳しいです!)。
-
TypeError: 'encoding'はこの関数の無効なキーワード引数です。
-
Pythonソケットプログラミング [WinError 10061] ターゲットコンピュータがアクティブに拒否しているため、接続できない。
-
ガールフレンドが深夜12時に彼女をベッドに急がせるよう頼んだが、私はそれをしないパイソンを持っています。
-
pyinstaller パッケージ生成 .exe 実行ファイルエラー "IndexError: tuple index out of range"