Python 開発環境管理ツール比較
最近LLMで記事を書くのが簡単になったので、ちょっとずつ公開を増やしていければと思います。まずは最近のPython開発環境についていろいろ新しいものが出てきたので調査結果を共有します。
概要
Python の開発環境管理は、目的に応じて複数のツールを組み合わせて使うのが現代的なアプローチです。本ドキュメントでは、各ツールの役割と使い分けを整理します。
ツールのカテゴリ分類
$$
\begin{array}{|l|l|l|} \hline \text{カテゴリ} & \text{役割} & \text{代表的なツール} \\ \hline \text{システム環境管理} & \text{OS レベルの依存関係、ツールチェーン} & \text{Nix} \\ \hline \text{言語バージョン管理} & \text{Python / Node / Rust などのバージョン切り替え} & \text{mise, pyenv, asdf} \\ \hline \text{仮想環境管理} & \text{プロジェクトごとの Python 環境隔離} & \text{venv, conda, pixi} \\ \hline \text{パッケージ管理} & \text{ライブラリのインストール・依存解決} & \text{uv, pip, Poetry, conda} \\ \hline \text{設定ファイル管理} & \text{シェル・エディタ等の設定同期} & \text{dotfiles (stow, chezmoi, home-manager)} \\ \hline \end{array}
$$
1. システム環境管理
Nix
$$
\begin{array}{|l|l|} \hline \text{項目} & \text{内容} \\ \hline \text{目的} & \text{完全に再現可能な環境構築} \\ \hline \text{スコープ} & \text{システム全体(言語、ライブラリ、ツール、設定)} \\ \hline \text{再現性} & \text{最高(flake.lock で完全固定)} \\ \hline \text{学習コスト} & \text{高い} \\ \hline \text{適用場面} & \text{CUDA / OpenCV などシステム依存が複雑な場合} \\ \hline \end{array}
$$
# flake.nix の例
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
outputs = { self, nixpkgs }: {
devShells.x86_64-linux.default =
let pkgs = nixpkgs.legacyPackages.x86_64-linux;
in pkgs.mkShell {
packages = [
pkgs.python311
pkgs.opencv
pkgs.cmake
];
};
};
}使い方:
nix develop # 開発シェルに入る2. 言語バージョン管理
mise vs pyenv vs asdf
$$
\begin{array}{|l|l|l|l|} \hline \text{項目} & \text{mise} & \text{pyenv} & \text{asdf} \\ \hline \text{実装} & \text{Rust} & \text{Shell} & \text{Shell} \\ \hline \text{速度} & \text{高速} & \text{普通} & \text{遅い} \\ \hline \text{対応言語} & \text{多言語} & \text{Python のみ} & \text{多言語(プラグイン)} \\ \hline \text{設定ファイル} & \text{.mise.toml} & \text{.python-version} & \text{.tool-versions} \\ \hline \text{環境変数管理} & \text{あり(direnv 相当)} & \text{なし} & \text{なし} \\ \hline \end{array}
$$
# .mise.toml
[tools]
python = "3.11"
node = "20"使い方:
mise use python@3.11
mise install推奨: mise(asdf の高速な後継、多言語対応)
3. 仮想環境管理
venv vs conda 系 vs pixi
$$
\begin{array}{|l|l|l|l|} \hline \text{項目} & \text{venv} & \text{conda/mamba} & \text{pixi} \\ \hline \text{実装} & \text{Python 標準} & \text{Python/C++} & \text{Rust} \\ \hline \text{速度} & \text{速い} & \text{遅い/速い} & \text{速い} \\ \hline \text{C ライブラリ依存解決} & \text{✗} & \text{✓} & \text{✓} \\ \hline \text{Python バージョン管理} & \text{✗} & \text{✓} & \text{✓} \\ \hline \text{パッケージソース} & \text{PyPI} & \text{conda-forge/defaults} & \text{conda-forge} \\ \hline \text{商用ライセンス} & \text{なし} & \text{Anaconda は制限あり} & \text{なし} \\ \hline \end{array}
$$
conda 系の変種
$$
\begin{array}{|l|l|} \hline \text{名称} & \text{説明} \\ \hline \text{Anaconda} & \text{フル版、商用利用に制限} \\ \hline \text{Miniconda} & \text{最小構成の conda} \\ \hline \text{Miniforge} & \text{conda-forge デフォルト、完全 OSS} \\ \hline \text{Mamba} & \text{conda 互換の高速版(C++ 実装)} \\ \hline \text{Micromamba} & \text{Mamba の単体実行ファイル版} \\ \hline \end{array}
$$
pixi
conda-forge エコシステムを使うモダンなツール。
# pixi.toml
[project]
name = "myproject"
channels = ["conda-forge"]
platforms = ["linux-64"]
[dependencies]
python = "3.11.*"
numpy = "*"
opencv = "*"pixi init
pixi add python numpy opencv
pixi run python main.py4. パッケージ管理(Python)
uv vs Poetry vs pip
$$
\begin{array}{|l|l|l|l|} \hline \text{項目} & \text{uv} & \text{Poetry} & \text{pip} \\ \hline \text{実装} & \text{Rust} & \text{Python} & \text{Python} \\ \hline \text{速度} & \text{非常に高速} & \text{普通} & \text{普通} \\ \hline \text{ロックファイル} & \text{uv.lock} & \text{poetry.lock} & \text{なし(pip-tools で対応)} \\ \hline \text{依存解決} & \text{✓} & \text{✓} & \text{基本的} \\ \hline \text{pyproject.toml} & \text{PEP 標準} & \text{独自拡張} & \text{PEP 標準} \\ \hline \text{Python バージョン管理} & \text{✓} & \text{✗} & \text{✗} \\ \hline \text{パッケージ公開} & \text{✓} & \text{✓} & \text{twine 併用} \\ \hline \end{array}
$$
uv(推奨)
uv venv
uv pip install numpy pandas
uv lock
uv sync
uv run python main.pyPoetry
poetry new myproject
poetry add numpy pandas
poetry install
poetry run python main.py移行の容易さ: Poetry → uv は比較的簡単
5. 設定ファイル管理(dotfiles)
管理ツール比較
$$
\begin{array}{|l|l|} \hline \text{ツール} & \text{特徴} \\ \hline \text{Git + シンボリックリンク} & \text{最もシンプル} \\ \hline \text{stow} & \text{ディレクトリ構造をそのままリンク} \\ \hline \text{chezmoi} & \text{テンプレート機能、マシン差分管理} \\ \hline \text{yadm} & \text{Git ラッパー、暗号化対応} \\ \hline \text{home-manager} & \text{Nix で宣言的に管理} \\ \hline
\end{array}
$$
典型的な構成
~/dotfiles/
├── .bashrc
├── .gitconfig
├── .config/
│ └── nvim/
└── install.shhome-manager(Nix 統合)
# home.nix
{
programs.git = {
enable = true;
userName = "Your Name";
extraConfig = {
init.defaultBranch = "main";
};
};
}推奨構成パターン
パターン A: シンプル(Web 開発、ツール開発)
mise → Python バージョン管理
uv → 仮想環境 + パッケージ管理メリット: 導入が簡単、高速、チームに広めやすい
mise use python@3.11
uv venv
uv pip install -r requirements.txtパターン B: 科学計算(numpy, OpenCV, CUDA)
pixi → Python + C ライブラリ依存(conda-forge)
uv → PyPI 専用パッケージの追加(必要なら)メリット: C ライブラリの依存解決が楽、商用制限なし
pixi init
pixi add python numpy opencv cuda-toolkit
pixi shellパターン C: 完全再現性(CI/CD、複雑な依存)
Nix → システムライブラリ、ツールチェーン
uv → Python パッケージメリット: 最高の再現性、CI と本番の環境差異を排除
nix develop
uv syncパターン D: ハイブリッド(段階的導入)
Nix → 特殊な依存(CUDA, ROS2)のみ
mise → 日常の言語バージョン管理
uv → Python パッケージメリット: 必要な部分だけ Nix の恩恵を受けられる
選択フローチャート
プロジェクトの依存は?
│
├─ 純粋な Python のみ
│ └─→ mise + uv
│
├─ C ライブラリ依存あり(numpy, OpenCV など)
│ ├─ 手軽さ優先 → pixi
│ └─ 再現性優先 → Nix + uv
│
└─ CUDA / ROS2 / 特殊なシステム依存
└─→ Nix + uv(または Docker)クイックスタートコマンド集
mise + uv(シンプル構成)
# mise インストール
curl https://mise.run | sh
# プロジェクトセットアップ
mise use python@3.11
uv venv
uv pip install -e ".[dev]"pixi(科学計算)
# pixi インストール
curl -fsSL https://pixi.sh/install.sh | bash
# プロジェクトセットアップ
pixi init
pixi add python=3.11 numpy scipy matplotlib opencv
pixi shellNix(完全再現性)
# Nix インストール(Determinate Systems 版)
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh
# プロジェクトセットアップ
nix flake init
nix developまとめ
$$
\begin{array}{|l|l|} \hline \text{優先事項} & \text{推奨構成} \\ \hline \text{手軽さ・速度} & \text{mise + uv} \\ \hline \text{C ライブラリ依存} & \text{pixi} \\ \hline \text{完全な再現性} & \text{Nix + uv} \\ \hline \text{チーム導入のしやすさ} & \text{mise + uv} \\ \hline \text{既存 conda 環境からの移行} & \text{pixi または mamba} \\ \hline \end{array}
$$
新規プロジェクトでは mise + uv をベースラインとし、必要に応じて pixi や Nix を追加するアプローチが現実的です。
便利な時代になったものですね。
