昨今まで、Pythonの開発環境は「VirtualBox+Vagrant」環境上のUbuntu仮想マシン内に構築してきました。
あくまで試作的な活動であり、スクラップ&ビルドを行い易い仮想マシン環境が都合が良かったためです。
Python関連のパッケージのインストールもシステム本体に対して実施しており、万が一問題が発生した場合は仮想マシンごと再構築すれば良いと考えていました。
しかし、機械学習に関わるような処理を行うようになると、必要となるメモリの量やGPUの使用などの関係で、仮想マシンでは逆にやりづらくなってきました。
よって、ホストマシン(Mac)で直接Pythonを動かすようになってきましたが、そうなるとシステム環境を直接更新することにはやはり抵抗があります。
と言うことで、今まで知識としては持っていましたが、なんとなく避けてきたvenvを改めて使ってみたいと思います。
Pythonの仮想環境(venv)
Pythonではプロジェクトごとに独立した実行環境を作ることができます。
言い換えると、プロジェクトごとに異なるバージョンのライブラリを使用したり、システム全体のPython環境を汚染したりせずに開発を進めることができると言うことです。
具体的には以下のように利用します。
環境構築
プロジェクトを管理するディレクトリにおいて以下のコマンドを実行します。
# python3 -m venv <仮想環境名>
上記により、同ディレクトリ直下に仮想環境名で指定した名称のサブディレクトリが生成され、その配下に追加パッケージ等が格納されるようになります。
仮想環境のアクティベート
仮想環境は作成しただけでは有効になりません。
有効にするためには以下のコマンドを実行します。
# source <仮想環境名>/bin/activate
実施していることは大まかには以下の4点のようです。
- “<仮想環境>/bin” にパスを通す
- 環境変数 “VIRTUAL_ENV” に仮想環境のパスを設定
- 仮想環境のディアクティベートを行う “deactivate” 関数を定義
- コマンドプロンプトの先頭に仮想環境名が表示されるように設定
上記の最後で示したように、アクティベート後はコマンドプロンプトに仮想環境名が表示されるようになるので、仮想環境が有効になっていることが一目で確認できて便利です。
パッケージの追加
仮想環境は大雑把に言えば「プロジェクトごとにパッケージを管理するための環境」であり、パッケージを追加しなければ意味がありません。
Pythonの特徴の一つが豊富なパッケージ群(特にAI関連)であると認識しているので、パッケージの追加を必要としないケースは稀かと思いますが。
Pythonのパッケージ管理ツールとしてはpipが有名ですが、仮想環境内ではpipが使用できるようになっています。
このpipを使用してパッケージの追加を行います。
# pip install <パッケージ名>
仮想環境のディアクティベート
仮想環境から抜けるには、以下のコマンドを実行します。
# deactivate
上記はアクティベートの際に定義されたシェル関数です。
Pythonプロジェクトのgit管理
Laravel(PHP)で開発されたプロジェクトにおいて、追加されたパッケージ群は “vendor” ディレクトリ配下に追加されますが、同ディレクトリはgitの管理対象外となります。
“vendor” 配下のファイル群は自製したものではありませんし、gitを経由しなくても入手できるものなので、対象外とすることは合理的です。
一方で、新規環境にgitを経由して展開したプロジェクトを動作可能にするためには “vendor” 配下の再生が必要であり、パッケージのバージョンも展開元の環境と合わせる必要があります。
この点を解決しているのがcomposerでした。
composerは “composer.lock” なるファイルに展開元でインストールされていたパッケージ群の各種情報を保持していて、これを元に “vendor” 配下を再生できるようになっていました。
Pythonプロジェクトにおいても仮想環境化にパッケージ群が追加されますが、これをgitで管理するのは非効率です。
PHPのcomposerのようにパッケージ情報の管理と環境の再構築ができる処理が必要になります。
この点を解決するのが “pip freeze” です(composerと比較して若干泥臭いですが…)。
パッケージ情報の保存
現在の環境にインストールされているパッケージ情報を保存するためには以下のコマンドを実行します。
# pip freeze > requirements.txt
上記により、”requirements.txt” にはパッケージ関連情報が格納されます。
具体的には以下のような内容です。
absl-py==2.2.0
astunparse==1.6.3
certifi==2025.1.31
...
Werkzeug==3.1.3
wrapt==1.17.2
zipp==3.21.0
composerと比較して、かなりシンプルな内容です。
なお、情報を保存するファイル名は何でも良いと思いますが、慣習的に “requirements.txt” が使われているケースが多いようですので、この名称を使用するのが分かりやすくて良いかと思います。
パッケージの展開
前述の “requirements.txt” の内容からパッケージを展開する方法は以下です。
# pip install -r requirements.txt
…と、多くのネット情報で書かれていますが、上記を “composer install” のイメージで実行すると失敗します。
“composer.lock” ファイルを含むプロジェクト環境をgitで新規展開した直後に “composer install” を実行すれば、展開元と同じパッケージ(バージョン含めて)がインストールされますが、Pythonの場合はそこまで単純ではありません。
まず、上記はpipコマンドを実行している訳ですが、そのためには同コマンドが存在し、パスが通っている必要があります。
また、”requirements.txt” にはパッケージの情報は含まれますが、仮想環境自体の情報が含まれる訳ではないので、仮想環境の構築自体は先に実施しておく必要があります。
つまり、正しい(不足のない)手順としては以下になります。
# python3 -m venv <仮想環境名>
# source <仮想環境名>/bin/activate
# pip install -r
“composer install” を実行することで “vendor” 環境が自動的に生成される、と言うような便利な機能にはなっていないと言うことです。
まとめ
Pythonに慣れ親しんだ人には当たり前の内容かと思いますが、私と同レベルの初心者向けに情報を残しておきます。
途中でも書きましたが、PHPと比較してPythonはパッケージ(特にAI関連)の豊富さが特徴であり、つまりは目的によって様々なパッケージの使い分けが必要になることから、特にvenvのような機能は有効かと思います。
“requirements.txt” でのパッケージ情報の管理に関しては、composerと比較して随分シンプルです。
composerの場合、パッケージの追加自体をcomposer経由で行うことでcomposer.lockファイルが自動的に更新されますが、”requirements.txt” はあくまで “pip freeze” の出力を保存しているだけのファイルであるため、不整合を発生させないためには適切に “requirements.txt” を更新していく必要があります。
この辺が利用者に託されている点は不便に感じるのですが、Pythonに関して知識が不足しているだけで、もっと効率的な方法があるのかもしれません。
まずは、最低限の目標である仮想環境の構築とgitでの管理と展開方法を確立できたと言うことで、今回は良しとしたいと思います。