🐍

Pythonの仮想環境構築 - パッケージ管理編

2022/03/26に公開

はじめに

この記事は以下の記事からの続編です。

https://zenn.dev/mook_jp/articles/1d915a0aef83a7

上記の記事にも記載していますが、pythonの仮想環境作成ツールには主に3つの分類があります。

  1. Python(インタプリタ)のバージョン切り替えを行うもの
  2. パッケージ切り替えを行うもの
  3. 2の機能に加えて独自のパッケージ管理機能を有するもの(pip以外のパッケージ管理を利用可能なもの)

今回は2.パッケージ切り替えを行うものをメインに記載していきます。

執筆時の環境

OS: Ubuntu 20.04.4 LTS
shell: zsh 5.8 (x86_64-ubuntu-linux-gnu)
python: Python 3.9.7 (pyenv内の仮想環境)

パッケージ管理の仮想環境

pyenvでは複数の Python 本体(インタプリタ)のバージョンを管理・切替て利用できますが、パッケージ管理を行うことには不向きだと思っています。

pyenv ではPythonのバージョン1つに対して1つのパッケージ管理環境しかないため、Pythonのバージョンを固定して、パッケージごとに複数のバージョンを試すようなことはできません[1]

今回は以下の3つのツールを使って説明します。

  • venv
  • Pipenv
  • Poetry

1. venv - Python標準機能

venvpython をインストールすると標準で組み込まれているパッケージ管理のための仮想環境構築ツールです。

仮想環境(プロジェクト)を作成する

それでは仮想環境を作成していきます。

zsh
$ mkdir ~/new-test-dir # 1. 仮想環境用のフォルダを作成する
$ cd ~/new-test-dir    # 2. 作成したディレクリに移動します
$ python -m venv .venv # 3. 仮想環境を作成
$ . .venv/bin/activate # 4. 有効化
コピペ用

コピペして使うために利用してください。

  1. 初めに仮想環境を作成するためのフォルダを作成します。
  2. 作成したフォルダへ移動する
bash - 仮想環境用のフォルダを作成する
mkdir ~/new-test-dir # 1. 仮想環境用のフォルダを作成する
cd ~/new-test-dir    # 2. 作成したディレクリに移動します
  1. 仮想環境を作成する(.venvという仮想環境フォルダが作成される)
  2. 仮想環境を有効化する
bash - 仮想環境の作成
python -m venv .venv # 3. 仮想環境を作成
. .venv/bin/activate # 4. 有効化

コマンドに関する説明

zsh
python -m venv <仮想環境ディレクトリ名>
source <仮想環境ディレクトリ>/bin/activate # source と . は同義です。ファイルを読み込む機能を提供します。
参考:pythonのオプション

-m mod: ライブラリモジュールをスクリプトとして実行する(オプションリストを終了させる)

zsh
$ python -h
	...【省略】
-m mod : run library module as a script (terminates option list)
	...【省略】

仮想環境を利用する

毎回利用する時に、source <仮想環境ディレクトリ名>/bin/activate または . <仮想環境ディレクトリ名>/bin/activate で仮想環境を有効化してください。

  • 仮想環境を有効化する
zsh
. <仮想環境ディレクトリ名>/bin/activate # . の代わりに source も利用できます
  • 仮想環境から抜ける
zsh
deactivate

コマンドが有効になったことを確認するには以下のコマンドで確認してください。
作成した <仮想環境ディレクトリ名> が表示されれば正常に有効化されています。

zsh
$ which python # 現在利用しているPythonのPathを表示します。
venvの利用イメージ.gif

venvの利用イメージ

パッケージのインストール/アンインストール

インストールやアンインストールも pip コマンドを利用して行います。

zsh
pip install pandas   # インストール
pip uninstall pandas # アンインストール

インストールしたパッケージの確認

インストールしたパッケージを一覧表示する

zsh
pip list

インストールした、パッケージの一覧を requirements.txt というファイルに出力する。

zsh
pip freeze > ./requirements.txt
requirements.txtというファイル名について

requirements.txt というファイル名を使わなくても pip のみを使って管理する場合は問題が発生することはありませんが。一般的にこのファイルの名称は requirements.txt で固定されています。

環境の再現

仮想環境のフォルダを移動して利用したり、<仮想環境ディレクトリ名>を変更したりすることはできません。そういった場合は、基本的に一度 requirements.txt を出力して作成して再度インストールする必要があります。

zsh
python -m venv <新しい仮想環境ディレクトリ名>
source ./<新しい仮想環境ディレクトリ名>/bin/activate
pip install -r ./requirements.txt

2. pipenv

pipenvPython Packaging Authority(一般的には PyPA) というワーキンググループによって作成されているパッケージ管理のための仮想環境構築ツールです。PyPAはPythonのパッケージ管理のツールを提供するためのグループみたいなもので、pipなどのツールもこちらで開発されています。

https://github.com/pypa/pipenv

Pipenv は、全てのパッケージングの世界 (bundler、composer、npm、cargo、yarnなどなど。) における最高のものをPythonの世界にもたらすことを目的としたツールです。 我々の世界ではWindowsは第一級市民です。
出展: Pipenv: 人間のためのPython開発ワークフロー

Pipenvのインストール

pipenv をインストールします。pipenv自身も PyPI
(Python Package Index) と呼ばれるpython用のサードパーティリポジトリにて公開されています。通常のモジュールをインストールと同様に pip を利用してインストールできます。

zsh
pip install pipenv
Python本体のバージョンについて

Pipenvで作成する仮想環境で利用するPython本体のバージョンは利用しているPythonのバージョンに依存します。以下のコマンドで表示されるバージョンが仮想環境にも適用されます。

zsh
python -V

Python本体のバージョンを切り替えるためには、この記事を確認し、pyenvをインストールしてください。

仮想環境(プロジェクト)を作成する

pipenv の仮想環境はディレクトリベースで管理されるため、まずは仮想環境を構築するディレクリを作成・移動してください。

zsh
mkdir ~/new-project # 仮想環境を作成したいディレクトリ作成します。
cd ~/new-project    # 作成したディレクリに移動します

プロジェクトを初期化します。

zsh
pipenv --python 3.7

コマンドが成功していれば、Pipfileが生成されます。

Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]

[dev-packages]

[requires]
python_version = "3.7"

これで仮想環境の構築と有効化が完了です。以後は作成したディレクトリに移動すると自動で仮想環境が有効化され、別のディレクトリに映ると自動で非有効化されます。

仮想環境を利用する

Pipenvでは現在のカレントディレクトリが(pwd) 仮想環境フォルダであれば、以下のようなコマンドが利用きます。

Pipenv Cheat Sheet
  • Pipenvの仮想環境有効にする
zsh
pipenv shell
  • Pipenvの仮想環境から抜ける
zsh
exit
  • 仮想環境を有効化せず仮想環境のPythonを実行する
zsh - (pip なども使えます)
pipenv run python
  • 有効になっている仮想環境の場所を表示する
    VSCodeなどで、Pythonのインタプリターを指定する際は、以下のコマンドで表示されたPathを指定してください。
zsh
pipenv --venv

パッケージのインストール/アンインストール

パッケージのインストールは以下のように行います。
また、インストールが完了すると Pipfile にパッケージ名が追加され、 Pipfile.lock というファイルが作成されます。

zsh
pipenv install pandas
Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
+pandas = "*"

[dev-packages]

[requires]
python_version = "3.9"

Pipenv.lock ファイルには実際にインストールされたパッケージの詳細や依存するパッケージの情報などが記載されています。

Pipfile.lock

開発用のパッケージのインストール

Pipenv では本番環境では利用しないが開発時には導入したいパッケージの導入を用意に行えます。

zsh
pipenv install --dev flake8 black mypy

開発用パッケージのインストールが完了すると、Pipfileが自動で更新されます。

Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
pandas = "*"

[dev-packages]
+flake8 = "*"
+mypy = "*"
+black = "*"


[requires]
python_version = "3.9"

環境の再現

  • requirements.txt を元に再現する
zsh
pipenv install -r ./requirements.txt
  • Pipfile を元に再現する
    Pipfileを元に環境を再現します。
zsh
pipenv install
pipenv install --dev # 開発環境も再現
  • Pipfile.lock を元に再現する
    バージョンを固定して再現する場合は、pipenv sync コマンドを利用しましょう。
zsh
pipenv sync
pipenv sync --dev # 開発環境も再現

スクリプトの登録

Pipenvでは仮想環境で利用するためのスクリプトを登録することができます。
例えば、flake8 によるコードプレビュー機能を登録することができます。

<script名> = "実行するコマンド"
start = "python main.py runserver"
test = "python -m unittest discover -v"
format = "autopep8 -ivr ."
lint = "flake8 --show-source ."

スクリプトの実行する

登録したスクリプトは pipenv run <スクリプト名> で実行できます。

pipenv run start    # [scripts]のstartを実行する例です
Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
pandas = "*"

[dev-packages]
flake8 = "*"
mypy = "*"
black = "*"

[scripts]
+start = "python main.py runserver"
+test = "python -m unittest discover -v"
+format = "autopep8 -ivr ."
+lint = "flake8 --show-source ."

[requires]
python_version = "3.9"

3. poetry

基本的には pipenv の機能と同等の機能を持っています。 Sébastien Eustace さんにより開発されています。pipenvに対する いくつかの不満 があり開発されたようです。
Python 3.7 以上をサポートしています。

https://github.com/python-poetry/poetry

https://cocoatomo.github.io/poetry-ja/cli/

Poetryのインストール

Poetry自体をインストールするには、python2.7以上またはpython3.5以上の環境が必要です。Pythonの環境がない場合は、pyenvをインストールしてください。

zsh
curl -sSL https://install.python-poetry.org | python3 -

Pathを通し、poetry コマンドを利用できるようにします。

zsh
echo 'export PATH="$HOME/.local/bin/:$PATH"' >> ~/.zshrc
Bashを利用している場合
echo 'export PATH="$HOME/.local/bin/:$PATH"' >> ~/.bashrc

tab補完の設定。zsh以外のシェルをご利用の方はこちらをご覧ください。

zsh
mkdir ~/.zfunc
poetry completions zsh > ~/.zfunc/_poetry
echo 'export PATH="$HOME/.local/bin/:$PATH"' >> ~/.zshrc
Bashを利用している場合
poetry completions bash > /etc/bash_completion.d/poetry.bash-completion
Python本体のバージョンについて

Pipenvで作成する仮想環境で利用するPython本体のバージョンは利用しているPythonのバージョンに依存します。以下のコマンドで表示されるバージョンが仮想環境にも適用されます。

zsh
python -V

Python本体のバージョンを切り替えるためには、この記事を確認し、pyenvをインストールしてください。

仮想環境(プロジェクト)を作成する

Poetryでは仮想環境を構築する前に、はじめに pyproject.toml を作成する必要があります。
pyproject.toml にプロジェクトに関する基本的な情報を全て格納してから、仮想環境を構築していきます。

プロジェクト作成の流れとしては

  1. pyproject.toml を作成する。 poetry init
  2. pyproject.toml を元にプロジェクトを初期化する。 poetry install

pyproject.toml を作成する

pyproject.tomlを作成するための、方法は大きく分けて4つあります。

  • 自動で生成する poetry new <プロジェクト名>
  • 対話形式で作成する poetry init
  • 手動で pyproject.toml必須事項(required)を入力する
  • GithubなどからCloneしたファイルを利用する

1.1 new コマンドを利用してプロジェクトを作成する

ほとんどのプロジェクトに適するディレクトリ構造を作成する

zsh
poetry new my-project

以下のようなディレクトリ構造を自動で構築します。

bash
tree ~/workspace/myproject
my-project
├── pyproject.toml
├── README.rst
├── my_package
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_my_package.py

1.2 new ディレクトリ名とは別のプロジェクト名をつける

poetry new my-folder --name my-project

1.3 new srcフォルダを利用する場合

poetry new --src  my-project

以下のような、ディレクリ構造を自動で作成します。

bash
tree ~/workspace/myproject
my-package
├── pyproject.toml
├── README.rst
├── src
│   └── my_package
│       └── __init__.py
└── tests
    ├── __init__.py
    └── test_my_package.py

2. init 対話形式でpyproject.tomlのみを作成する

poetry init

以下のような質問を対話形式で入力します。

zsh
This command will guide you through creating your pyproject.toml config.

Package name [workspace]:  <プロジェクト名>
Version [0.1.0]:  <プロジェクトのバージョン>
Description []:  <プロジェクトに関する説明>
Author [mook-jp <example@email.com>, n to skip]:  <プロジェクトの開発者名>
License []:  <ライセンス>
Compatible Python versions [^3.9]:  <Pythonのバージョン>

Would you like to define your main dependencies interactively? (yes/no) [yes] <依存関係を登録しますか?>
Generated file

pyproject.tomlが作成されます。

pyproject.toml
[tool.poetry]
name = "プロジェクト名"
version = "プロジェクトのバージョン"
description = "プロジェクトに関する説明"
authors = ["プロジェクトの開発者名"]
license = "ライセンスを入力する"

[tool.poetry.dependencies]
python = "Pythonのバージョン"

[tool.poetry.dev-dependencies]

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

プロジェクトの初期化

installコマンドを利用して、現在のプロジェクトにある pyproject.toml ファイルを読み込み、依存関係を解決し、インストールします。

zsh
poetry install

poetry install コマンドは現在のプロジェクト内に poetry.lock ファイルがある場合は、依存関係を解決する代わりに、 poetry.lock 内にあるバージョンを利用します。

オプションの利用

開発用の依存関係をインストールしたくない場合は、--no-devオプションを利用する

zsh
poetry install --no-dev

プラットフォームごとにインストールするライブラリを変更する。--no-rootオプションを利用する。

https://zenn.dev/hrsma2i/articles/poetry-extras

zsh
poetry install --extras gpu

仮想環境を利用する

Pipenvでは現在のカレントディレクトリが(pwd) 仮想環境フォルダであれば、以下のようなコマンドが利用きます。

  • Pipenvの仮想環境有効にする
zsh
poetry shell
  • Pipenvの仮想環境から抜ける
zsh
exit
  • 仮想環境を有効化せず仮想環境のPythonを実行する
zsh - (pip なども使えます)
poetry run python

パッケージのインストール/アンインストール

パッケージのインストールは以下のように行います。
また、インストールが完了すると pyproject.toml にパッケージ名が追加され、 poetry.lock というファイルが作成されます。

インストール

zsh
poetry add pandas
pyproject.toml
[tool.poetry]
name = "my-project"
version = "0.1.0"
description = ""
authors = ["mook <mook@example.com>"]

[tool.poetry.dependencies]
python = "^3.9"
+pandas = "^1.4.1"

[tool.poetry.dev-dependencies]
pytest = "^5.2"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

poetry.lock ファイルには実際にインストールされたパッケージの詳細や依存するパッケージの情報などが記載されています。

poetry.lock

アンインストール

remove コマンドは、現在のインストールされたパッケージの一覧からパッケージを削除します。

poetry remove pandas

パッケージのアップデート

最新バージョンの依存関係を取得し、 poetry.lock を更新するには、 update コマンドを使いましょう。このコマンドはプロジェクトのすべての依存関係を解決し、厳密なバージョンを
poetry.lock に書き込みます。

zsh
poetry update

一部のみを更新したい場合は、poetry update <アップデートするパッケージ>のように指定できます。

zsh
poetry update requests

開発用のパッケージのインストール

Pipenv では本番環境では利用しないが開発時には導入したいパッケージの導入を用意に行えます。

zsh
poetry add --dev flake8 black mypy

開発用パッケージのインストールが完了すると、Pipfileが自動で更新されます。

pyproject.toml
[tool.poetry]
name = "my-project"
version = "0.1.0"
description = ""
authors = ["mook <mook@example.com>"]

[tool.poetry.dependencies]
python = "^3.9"
pandas = "^1.4.1"

[tool.poetry.dev-dependencies]
pytest = "^5.2"
+flake8 = "^4.0.1"
+black = "^22.1.0"
+mypy = "^0.942"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

環境の再現

pyproject.toml または poetry.lock を元に環境を再現できます

poetry.lock ファイルが今のディレクトリにある場合は、依存関係を解決する代わりに、ロックファイルにある厳密なバージョンを使います。 これにより、そのライブラリを使う全員が同じバージョンの依存関係を手に入れることを保証します。
poetry.lock ファイルが無い場合は、Poetryは依存関係解決の結果に従ってロックファイルを作成します。

zsh
poetry install

スクリプトの登録

PoetryにPipenvのようなタスクランナー機能はありあません。
そんため、タスクランナーのような機能を利用するには別途用意する必要があります。

まだないだけのようなので、待てば提供されるかもしれません。

https://github.com/python-poetry/poetry/pull/591#issuecomment-504762152

脚注
  1. pyenvにもそのような機能を提供するツールは用意されていますが、別途インストールする必要があるため今回は説明しません。 ↩︎

Discussion