状況
venvで環境を作成する際,プロジェクトのホームディレクトリにて以下のようなコマンドで行う.
pyenv local 3.x.x # 使用したいバージョン(設定していなければ)
python -m venv .venv # .venvという名前でvenvのディレクトリ・ファイルが作成される
この時,プロジェクト内に作成される固有の.venvディレクトリは以下の通り.
.venv
├─Scripts
├─Lib
├─Include
└─pyvenv.cfg
この中で,pyvenv.cfgは以下の通り.
home = C:\Users\username\.pyenv\pyenv-win\versions\3.x.x # .pyenvの場所による
include-system-site-packages = false
version = 3.x.x
pyvenv.cfgは作成されたファイル類の中で,このvenvの所属元となるpython.exeの場所を示すっぽい.
この時,home = C:\Users\username\.pyenv\pyenv-win\versions\3.x.x
はusername
というようなデバイス由来のパスになってしまう.そのため,Git
などで別のPCで同プロジェクトの開発を行う際にそのままでは実行できない.PCを変える際にいちいちpyvenv.cfgのパスを変更するのは面倒くさいし,忘れそう.
ここでは,上記を解決する.
解決手順
settings.jsonに手を加えずに,また,余計な環境変数を作成せずにcfgファイル内のitsutを書き換えるのみで,環境に応じてユーザー名を動的に読み替える方法に取り組む。
まず、pyvenv.cfgは静的なファイルなので、動的な読み替えが直接はできないが、仮想環境の有効化時にスクリプトを実行して適切に設定することが可能である。
pyvenv.cfg ファイル内のパスを動的に変更するためには、スクリプトを利用してユーザー名に応じてパスを書き換える方法が考えられる。
スクリプトの作成
仮想環境を有効化する前に、pyvenv.cfg ファイルの内容をユーザー名に基づいて書き換えるスクリプトを作成する。
例えば、PowerShellスクリプトを使用する場合,もしくはコマンドプロンプトを使用する場合:
PowerShell スクリプト (update_pyvenv.ps1)
$username = $env:USERNAME
$pyvenvPath = "プロジェクトのパス\venv\pyvenv.cfg"
(Get-Content $pyvenvPath) -replace 'C:\\Users\\.*?\\\.pyenv', "C:\\Users\\$username\\.pyenv" | Set-Content $pyvenvPath
cmd バッチファイル (update_pyvenv.bat)
@echo off
setlocal enabledelayedexpansion
set "username=%USERNAME%"
set "pyvenvPath=プロジェクトのパス\venv\pyvenv.cfg"
for /f "delims=" %%i in ('type "%pyvenvPath%"') do (
set "line=%%i"
set "line=!line:C:\Users\=.*?\.pyenv=C:\Users\%username%\.pyenv!"
echo !line! >> "%pyvenvPath%.tmp"
)
move /y "%pyvenvPath%.tmp" "%pyvenvPath%"
スクリプトで実行する場合
仮想環境を有効化する前に、このスクリプトを実行する。以下のように仮想環境を有効化する手順の前にスクリプトを呼び出す。
PowerShellの場合
.\update_pyvenv.ps1
venv\Scripts\activate
cmdの場合
call update_pyvenv.bat
venv\Scripts\activate
一連の処理をまとめた.ps1ファイルの作成
以下はPowerShellスクリプト (setup_env.ps1) でユーザ名を書き換え、仮想環境を作成し、Pythonのパスを確認する一連のコマンドを自動化する方法である。
PowerShellスクリプト (setup_env.ps1)
# ユーザー名を取得
$username = $env:USERNAME
# pyvenv.cfgのパスを設定
$pyvenvPath = "プロジェクトのパス\venv\pyvenv.cfg"
# pyvenv.cfgのhomeディレクトリをユーザー名に基づいて書き換える
(Get-Content $pyvenvPath) -replace 'C:\\Users\\.*?\\\.pyenv', "C:\\Users\\$username\\.pyenv" | Set-Content $pyvenvPath
# 仮想環境を再作成
python -m venv venv
# 仮想環境を有効化
. .\venv\Scripts\activate
# Pythonのバージョンを確認
.\venv\Scripts\python.exe --version
小話:.\venv\Scripts\python.exe と venv\Scripts\python.exe の違い
-
.\venv\Scripts\python.exe: 現在のディレクトリにある venv フォルダの Scripts フォルダ内の python.exe を指定している。.\ は現在のディレクトリを指し示すため、WindowsのコマンドプロンプトやPowerShellで使用される。
-
venv\Scripts\python.exe: 同じく venv フォルダの Scripts フォルダ内の python.exe を指定しているが、現在のディレクトリがすでに仮想環境のルートである場合は、.\ を省略しても問題ない。
実質的に、これらのコマンドは同じ場所を指し示している限り、同じ動作をする。ただし、スクリプトやコマンドラインでの明確さを保つために、.\ を付けることで、現在のディレクトリからの相対パスであることを明確にするのが一般的であるらしい。
スクリプトの実行
PowerShellで以下のコマンドを実行してスクリプトを実行する。
.\setup_env.ps1
これで、ユーザー名に基づいて pyvenv.cfg ファイルを更新し、仮想環境を再作成し、有効化してPythonのバージョンを確認する一連の操作が自動で行われるようになる。