uvを入れたら、環境構築が速くなりました。
ただし、最初の1時間は「速いけど、私は何をしているんだ」という顔でターミナルを見ていました。venv、pip、requirements.txtに慣れた人ほど、少しだけ足元が揺れます。
結論から言うと、今は新しい小物ツールならuvで始めています。90秒で作って、3分で動かして、5分で捨てられる軽さがあります。
何がうれしかったのか
Pythonの環境構築は、毎回少しずつ面倒です。
python -m venv .venv、有効化、pip更新、requirements作成。1つずつは小さいのですが、夜中に小さな自動化スクリプトを作りたいだけの時には重く感じます。
uvは、このあたりをかなり短くしてくれます。特に「試す」「消す」「また作る」が速いです。
最小の始め方
新しいフォルダで始めるなら、私はこうしています。
mkdir uv-lab
cd uv-lab
uv init
uv add requests
uv run python main.py
main.py はこんな感じです。
import requests
def main() -> None:
response = requests.get("https://example.com", timeout=10)
# ハマりポイント: timeoutなしのHTTPアクセスは待ち続けることがある
print(response.status_code)
if __name__ == "__main__":
main()
この短さは強いです。依存関係を入れて実行するまでの手数が減ると、試す心理的なハードルが下がります。
3回つまずいたところ
1回目は、既存のvenv感覚で有効化しようとしたことです。もちろん有効化して使う場面もありますが、uvは uv run で実行するのが気持ちいいです。
2回目は、requirements.txt を探したことです。uvでは pyproject.toml とロックファイルを中心に考える場面が増えます。ここで少し頭を切り替える必要がありました。
3回目は、古いプロジェクトへいきなり入れようとしたことです。依存関係が多い場所で初手から移行すると、速さより不安が勝ちます。
最初は新規の小さなツールで試すのが正解でした。
私が使っているテンプレート
小さなCLIツールなら、だいたいこの形で始めます。
from pathlib import Path
def read_text(path: Path) -> str:
if not path.exists():
raise FileNotFoundError(f"not found: {path}")
return path.read_text(encoding="utf-8")
def main() -> None:
path = Path("input.txt")
text = read_text(path)
# ハマりポイント: 最初に件数だけ出すと、文字化けや空ファイルに気づきやすい
print(f"chars={len(text)}")
if __name__ == "__main__":
main()
そして実行はこうです。
uv run python main.py
この「毎回同じ入り口」が地味に大切です。Claude Codeに修正を頼む時も、実行コマンドが固定されていると説明が短く済みます。
既存プロジェクトへの導入は慎重に
uvが速いからといって、すべての既存プロジェクトを一気に移行する必要はありません。
私も最初は、手元の古いPythonツールを3つまとめて移行しようとしました。結果、依存バージョンの違いを追う時間が増え、何のために移行しているのか分からなくなりました。
今はルールを決めています。
新規ツールはuv。既存で安定しているものは触らない。依存が壊れているものだけ、修理ついでにuv化する。
このくらいが一番落ち着きます。
requirements.txt派の逃げ道
uvに寄せるといっても、相手に渡す時は requirements.txt が必要な場面もあります。
私はここで一度、相手の環境を見ずに pyproject.toml 前提で渡してしまい、説明が長くなりました。新しい道具を使うことと、相手の手元で動くことは別問題です。
必要なら、依存関係を書き出しておくと安心です。
uv pip freeze > requirements.txt
ただし、何でも書き出せばよいわけではありません。検証で入れただけのライブラリまで残すと、あとで「これは何に使うんでしたっけ」となります。
私の小さなルールは、依存を追加したら30秒だけ理由を書くことです。
# pyproject.tomlのdependenciesを見て、不要なものを残さない
dependencies = [
"requests>=2.32.0", # HTTP取得に使う
]
速い環境構築は気持ちいいですが、1週間後の自分が読めない依存関係はただの負債です。
消しやすい環境は試しやすい
uvで気に入ったのは、作る速さだけではありません。消す心理的な軽さも大きいです。
私は以前、小さな検証フォルダを残し続けて、似た名前のプロジェクトが7個並んだことがあります。どれが最新か分からず、結局また新しく作りました。これはかなり無駄です。
今は、検証開始時に期限を決めます。
uv-lab-20260514
目的: requestsの挙動確認
期限: 今日中に残すか消すか決める
小さな README.md にこれだけ書いておくと、あとで判断できます。残すなら名前を変える。不要なら消す。uvの速さは、この「捨てる判断」と相性がいいです。
環境構築が重いと、試作を大事にしすぎます。軽いと、試作を試作のまま扱えます。これは地味ですが、かなり大きな変化でした。
Claude Codeとの相性
Claude Codeに「このプロジェクトはuvで動かします」と伝えると、実行や依存追加の提案が揃いやすくなります。
このプロジェクトはuvを使っています。
依存追加は uv add、実行確認は uv run python main.py でお願いします。
この一文を最初に入れるだけで、提案のズレが減りました。AIに環境の前提を渡すのは、思った以上に効きます。
まとめ
uvは、Python環境構築を劇的に変えるというより、試作の摩擦を小さくしてくれる道具でした。
90秒で環境を作り、3分で実行し、不要なら消す。この軽さは、小さな自動化を積み上げる人にはかなり効きます。
Pythonの環境構築で大事なのは、全部を新しくすることではなく、次の1本を迷わず始められることです。

コメント