Pythonの AIコーディング環境は2025〜2026年にかけて大きく変わった。旧来の requirements.txt + pip + flake8 + black スタックは、依存関係管理に uv、リントとフォーマットに ruff、単一設定ソースとして pyproject.toml を使う構成に大幅に置き換えられている。1年前に書かれた CLAUDE.md は、Claude を古いスタックに誘導しているかもしれない。
このガイドは2026年の Python プロジェクト向けに、完全で本番対応の CLAUDE.md テンプレートを提供する。FastAPI・Django・データサイエンスのワークロード別バリエーション付きだ。
Python で CLAUDE.md が必要な理由
Python は多くの言語よりエコシステムの断片化が激しい。同じプロジェクトが3種類の依存関係マネージャー(pip・poetry・uv)、2種類のフォーマット/lint パラダイム(ruff 以前のスタック vs. ruff)、3つの主要テストフレームワーク(pytest・unittest・nose)、そして極めて異なる型注釈の厳密さレベルを使いうる。
Claude はこれらすべてでトレーニングされている。明示的なガイダンスなしに、何らかの組み合わせを選ぶ——おそらくあなたのものではない。よくある問題:
uv syncを使うリポジトリでpip installを使うX | Noneの代わりにtyping.Optionalをインポートする(Python 3.10+ 構文)list[str]の代わりにList[str]を書く(3.9以前のスタイル)pyproject.tomlを編集する代わりにrequirements.txtを更新する- プロジェクトのロガーではなく
print()でデバッグ出力する
適切に設定された CLAUDE.md はこれらのほとんどを事前に防ぐ。
ユニバーサル Python ベーステンプレート
このベースはほぼすべての Python プロジェクトに適用できる。以下のフレームワーク固有セクションで拡張する。
# Project
[1文の説明。スタック、目的、それだけ。]
## Python Version
Python 3.12(最低 3.11)。モダン構文を使う:
- `Optional[X]` ではなく `X | None`
- `List[str]` ではなく `list[str]`
- `Dict[str, Any]` ではなく `dict[str, Any]`
- `Tuple[int, str]` ではなく `tuple[int, str]`
- 型エイリアスには `type X = ...`(Python 3.12)
- enum/型ディスパッチには適切な場所で match 文
## Commands
```bash
# インストール / 同期
uv sync # dev を含む全依存関係インストール
uv sync --no-dev # 本番依存関係のみ
uv add <package> # 依存関係追加
uv add --dev <package> # dev 依存関係追加
# 実行
uv run python -m app # またはプロジェクトの起動方法に合わせて
uv run fastapi dev # FastAPI プロジェクト用
# テスト
uv run pytest # 全テスト
uv run pytest tests/unit/ # ユニットテストのみ
uv run pytest -k "test_auth" # 名前でフィルタ
uv run pytest -x # 最初の失敗で停止
uv run pytest --cov=src --cov-report=term-missing # カバレッジ付き
# Lint とフォーマット
uv run ruff check . # lint
uv run ruff check --fix # 自動修正付き lint
uv run ruff format . # フォーマット
# 型チェック
uv run mypy src/
Off-Limits
pyproject.toml—[build-system]・[tool.ruff]・[tool.mypy]セクションを変更しないuv.lock— 手動編集禁止; 依存関係の変更後はuv syncを実行requirements.txtを追加しない — このプロジェクトはuvのみ使用
Code Style
ruff が強制。主要ルール:
- 行長: 88(Black 互換)
- インポート順: stdlib → サードパーティ → ローカル、空行で区切る
- 未使用インポートなし — ruff が検出する
.format()と%フォーマットより f-string- パターンマッチ代入にのみウォルラス演算子(
:=)
型注釈の必須箇所:
- すべての関数シグネチャ(パラメータ + 戻り値の型)
- クラス属性
- 明らかなプリミティブでないモジュールレベル変数
Anti-Patterns
- 裸の
except:なし — 常にexcept SpecificError:かexcept (Error1, Error2): from module import *なし- デバッグ出力に
print()なし —logging.getLogger(__name__)を使う - 認証情報や接続文字列のハードコードなし — 環境変数を使う
- ミュータブルなデフォルト引数なし:
def f(x: list = [])は間違い - 理由なしの
type: ignoreコメントなし - 本当に必要な場合を除き
Anyなし(なぜ必要かドキュメント化する)
Testing Conventions
fixture を使った pytest、本当に継承が必要な場合を除きテストクラスなし。
テストファイル: tests/unit/test_<module>.py、tests/integration/test_<feature>.py
# 良いテスト構造
def test_function_does_thing_when_condition(
some_fixture: SomeType,
) -> None:
# arrange(準備)
...
# act(実行)
result = function_under_test(some_fixture)
# assert(検証)
assert result == expected
# 複数ケースのパラメータ化
@pytest.mark.parametrize("input,expected", [
("case1", result1),
("case2", result2),
])
def test_function_handles_cases(input: str, expected: str) -> None:
assert function(input) == expected
非同期テスト: asyncio 直接ではなく anyio の @pytest.mark.asyncio。
タスク完了前の確認事項
-
uv run ruff check .が通る -
uv run ruff format --check .が通る -
uv run mypy src/が新しいエラーなしで通る -
uv run pytestが通る - すべての新しい関数/メソッドに型注釈がある
- 新しいパブリック関数に docstring がある
## FastAPI 固有テンプレート
```markdown
# Project
[概要説明] を提供する FastAPI REST API。
## Commands
```bash
uv run fastapi dev src/app/main.py # ホットリロード付き dev
uv run fastapi run src/app/main.py # 本番モード
uv run pytest tests/ -v # API を含む全テスト
Project Structure
src/
app/
main.py # FastAPI アプリインスタンス、ルーター登録
routers/ # ドメインごとに1ファイル(auth.py, users.py)
models/ # SQLAlchemy ORM モデル
schemas/ # Pydantic リクエスト/レスポンススキーマ
dependencies/ # FastAPI 依存性注入
services/ # ビジネスロジック(HTTP の懸念なし)
repositories/ # データアクセス層
core/
config.py # pydantic-settings BaseSettings
database.py # engine、セッションファクトリー
security.py # 認証ユーティリティ
tests/
conftest.py # 共有 fixture
unit/ # サービス/リポジトリ層、HTTP なし
integration/ # DB に対する httpx TestClient テスト
依存性注入パターン
FastAPI の依存システムを使う。ルーター関数内で db・config・current_user に直接アクセスしない。
# 良い例
@router.get("/users/{user_id}")
async def get_user(
user_id: int,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
user_service: UserService = Depends(get_user_service),
) -> UserResponse:
return await user_service.get_user(db, user_id, current_user)
# 絶対にやらない
@router.get("/users/{user_id}")
async def get_user(user_id: int) -> UserResponse:
db = next(get_db()) # 間違い
...
Anti-Patterns(FastAPI 固有)
response_model=Noneなし — 常にレスポンスモデルを指定する- DB 操作に同期ルートハンドラなし —
async defを使う - ルートハンドラ内で
db.commit()なし — サービス層を使う - ルーターにビジネスロジックなし — ルートは調整、サービスが計算
session.execute(text("raw SQL"))なし — ORM を使う
## Django 固有テンプレート
```markdown
# Project
[概要説明] のための Django アプリケーション。Django 5.x、Python 3.12。
## Commands
```bash
# 実行
uv run python manage.py runserver
# データベース
uv run python manage.py makemigrations
uv run python manage.py migrate
# テスト
uv run pytest # 全テスト
uv run pytest apps/users/tests/ # 特定アプリ
uv run pytest --reuse-db # テスト DB 再利用(高速)
Database Rules
- ORM 経由のデータベースアクセスのみ。ORM で表現できない複雑な集計を除き生 SQL なし(
RawSQLは控えめに、なぜ必要か文書化) - N+1 を避けるため
select_related()とprefetch_related()を常に使う - マイグレーション: モデル変更後は必ず
makemigrationsを実行。マイグレーションファイルを手動編集しない - ループ内で
save()を呼ばない —bulk_create()かbulk_update()を使う
Anti-Patterns(Django 固有)
views.pyにビジネスロジックなし —services.pyのサービス関数を使う- 他のモデルにアクセスするモデルメソッドなし — モデルはデータのみ
- アプリコードで
django.conf.settingsを直接インポートしない - ビューで
User.objects.all()なし — 常に現在のユーザーのスコープにフィルタ - ビジネスロジックにシグナルなし — 明示的なサービス呼び出しのみ
## データサイエンス テンプレート
```markdown
# Project
[ML/データパイプラインプロジェクトの説明。]
## Python Version
Python 3.12。適用可能な場合 NumPy 2.x 構文。
## Computation Rules
- 配列計算には Python ループよりも NumPy 操作
- パフォーマンスが重要な場合を除き NumPy 配列のインプレース変更なし(理由を文書化)
- Pandas: 変換チェーンに `pd.DataFrame.pipe()` を使用; チェーンインデックスを避ける
- 数値コードの型注釈: `np.ndarray` ではなく `npt.NDArray[np.float64]`
- 乱数状態: 常に `random_state=42` を渡すか、シード済み RNG を使う — シードなしは禁止
## Experiment Tracking
MLflow が設定済み。すべての実験実行で:
- `mlflow.log_params()` でハイパーパラメータをログ
- `mlflow.log_metric()` でエポックごとのメトリクスをログ
- `mlflow.log_artifact()` でモデルアーティファクトを保存
未トラッキングの実験なし — 実行する価値があるなら、トラッキングする価値もある。
## Anti-Patterns(データサイエンス固有)
- ハードコードされたファイルパスなし — プロジェクトルートからの相対 `pathlib.Path` を使う
- `df.iterrows()` なし — ベクトル化または控えめに `.apply()` を使う
- 訓練/テストデータのリーク — 前処理は訓練でフィット、テストで変換
- git にモデルアーティファクトをコミットしない — MLflow アーティファクトストアを使う
- ノートブックのみのロジックなし — 再利用可能な関数を `src/` モジュールに抽出
CLAUDE.md を最新に保つ
Python プロジェクトは速く進化する。CLAUDE.md が最も頻繁に古くなる箇所:
依存関係マネージャーの変更。 Poetry から uv に切り替えると、CLAUDE.md のすべてのコマンドを更新する必要がある。関連する PR に CLAUDE.md の更新メモを追加する。
Python バージョンアップ。 最低 Python バージョンが上がると、型構文の推奨が変わりうる。型エイリアスの type X = Y 構文は 3.9 では使えなかった。
フレームワークのメジャーバージョン。 Django 5.x、FastAPI 0.115+、Pydantic v2 はすべて API を変更した。CLAUDE.md が古いバージョン向けに書かれていると、Claude は非推奨パターンを生成する。
テストフレームワークの移行中。 多くのプロジェクトが unittest から pytest への移行途中だ。その状態なら CLAUDE.md に明記する: 「新しいテストは pytest を使い、unittest ではない。unittest スタイルのテストを見かけたらレガシーコードだ——追加しない」。
シンプルなプロセス: Claude 生成の Python コードに古いパターンがある PR をレビューしたとき、同じ PR で CLAUDE.md を更新する。
関連リソース
ルールを効果的にするものと CLAUDE.md アンチパターンについては CLAUDE.md ベストプラクティス を参照。プロジェクトタイプ別テンプレートの全ライブラリは 用途別 CLAUDE.md テンプレート10選 で。クロスツール環境での CLAUDE.md と AGENTS.md の比較は フォーマット比較ガイド で確認できる。