- Pythonの仮想環境って何してるのか気になって調べてみました。
python3 -m venvはプロジェクト内に専用のパッケージ置き場を作ります。- 複数のプロジェクトを開発していると、パッケージの更新で思わぬところに影響が出てくるもの。
- そういう悩みが一つ減るのは嬉しい。
そもそも仮想環境とは何か
macOSでPython開発をする際、python3 -m venvコマンドを使った仮想環境の作成が推奨されています。しかし、この仮想環境が実際にどのような仕組みで動作し、システムのファイル構造にどのような変化をもたらすのかはちょっとわかりにくいです。
仮想環境は、Pythonプロジェクトごとに独立したパッケージ管理空間を作る仕組みです。これは、プロジェクトAで使うライブラリのバージョンと、プロジェクトBで使うライブラリのバージョンが異なる場合でも、それぞれを独立して管理できるようにする技術です。
-m venvコマンドの詳細な仕組み
python3 -m venv myenvは、「Python標準ライブラリのvenvモジュールを使って、独立した実行環境を構築する」ためのコマンドです。
-mオプションは「モジュールをスクリプトとして実行する」という指示です。
つまり、venv というPython標準ライブラリのモジュール1を呼び出し、仮想環境作成処理を開始します。venvモジュールは、指定されたディレクトリ名(この場合はmyenv)で新しいフォルダを作成し、その中に独立したPython実行環境を構築します。
このプロセスでは、現在使用しているPythonインタープリターへの参照と、独立したパッケージインストール領域が準備されます。
もし、仮想環境を使わないと?
通常、Python パッケージをpip installでインストールすると、システム全体で共有される場所に保存されます。macOSでは通常、/usr/local/lib/python3.x/site-packagesや~/.local/lib/python3.x/site-packagesといった場所です2。
この方法では、すべてのPythonプロジェクトが同じパッケージ群を参照します。プロジェクトAで新しいバージョンのライブラリをインストールすると、プロジェクトBでも自動的にそのバージョンが使われることになります。
ファイルシステムに作られる構造
一方、仮想環境を作成すると、指定した名前のディレクトリ内に特定の構造が生成されます。macOSの場合、以下のような構造になります。
myenv/
├── bin/
│ ├── activate
│ ├── python
│ ├── python3
│ └── pip
├── lib/
│ └── python3.x/
│ └── site-packages/
├── include/
└── pyvenv.cfg
Code language: PHP (php)
- binディレクトリには、この仮想環境専用のPythonインタープリターとpipコマンドが配置されます。
これらは実際にはシステムにインストールされたPythonへのシンボリックリンク3(ショートカットのようなもの)です。 lib/python3.x/site-packagesディレクトリが最も重要な部分です。
ここに、この仮想環境でインストールしたパッケージがすべて保存されます。pyvenv.cfgファイルには、この仮想環境の設定情報が記録されています。
どのPythonバージョンを基にしているか、システムのsite-packagesを参照するかどうかなどの情報が含まれます。
仮想環境有効化の仕組み(PATHの変更)
source myenv/bin/activateコマンドを実行すると、シェル環境変数が変更されます。具体的には、PATH環境変数の先頭に仮想環境のbinディレクトリが追加されます。
これにより、pythonやpipコマンドを実行した際に、システム全体のものではなく、仮想環境内のものが優先的に実行されるようになります。また、VIRTUAL_ENV環境変数4が設定され、現在どの仮想環境が有効になっているかがシステムに記録されます。
パッケージインストール時の動作(site-packages)
仮想環境が有効な状態でpip installを実行すると、パッケージは仮想環境のsite-packagesディレクトリにインストールされます。Pythonがモジュールを読み込む際も、まず仮想環境のsite-packagesを確認し、見つからない場合にシステムの標準ライブラリを参照します。
この仕組みにより、各プロジェクトは独自のsite-packagesディレクトリを持ちます。プロジェクトAでバージョン2.0のライブラリをインストールし、プロジェクトBでバージョン1.5を使い続けることが可能になります。プロジェクト固有の依存関係を他のプロジェクトに影響を与えずに管理できるわけです。
まとめ
Python仮想環境は、プロジェクトごとに独立したsite-packagesディレクトリを作成し、環境変数の操作により実行時のパッケージ参照先を切り替える仕組みです。これにより、異なるプロジェクト間でのパッケージバージョン競合を回避し、依存関係を明確に管理できます。
- venvモジュールはPython 3.3から標準ライブラリに追加されました。それ以前はサードパーティのvirtualenvツールを使用する必要がありました。 – venv — Creation of virtual environments — Python 3.13.4 documentation
- macOS Catalina以降では、システムの整合性保護(SIP)により、システムPythonの変更が制限されています。これが自分でPythonをインストールすることが推奨される理由の一つです。 – System Integrity Protection (SIP) – macOS Security
- シンボリックリンクはUnix系システムでファイルやディレクトリへのショートカットのような機能です。venvはディスク容量の節約とパフォーマンス向上のためにコピーではなくシンボリックリンクを使用します。 – How do Python Virtual Environment Symlinks Work? – Stack Overflow
- VIRTUAL_ENV環境変数は仮想環境のパスを保存し、現在どの仮想環境が有効かを示します。しかし、仮想環境を直接実行することも可能なため、この変数の存在だけで仮想環境の使用を判断すべきではありません。 – What is the VIRTUAL_ENV environment variable used for – Stack Overflow