✍️ 필사 모드: Python 完全ガイド — FastAPI・AsyncIO・Pydantic・uv・Polars・AI エンジニアリング (Season 2 Ep 5, 2025)
日本語はじめに — 2025 年の Python は 2015 年の Python ではない
10 年前に Python を学んで戻ってきた人が最も驚く変化:
- uv (2024): pip・poetry・pyenv・pip-tools をすべて置き換える Rust 製統合ツール。10〜100 倍高速
- Pydantic v2 (2023): 検証エンジンを Rust で書き直し。5〜50 倍高速
- FastAPI: Type Hints ベース API フレームワークの事実上の標準
- Polars (2024〜): Pandas 代替。Rust 製、10〜100 倍高速、メモリ効率
- Python 3.13 (2024/10): Free-threading (No-GIL) 実験、JIT コンパイラ、改善 REPL
- LangChain・LangGraph・Pydantic AI (2024〜): AI エージェントスタック
- Ruff + mypy/pyright: Lint・Format・型チェックを高速ツールに総入れ替え
Python は「AI エンジニアリングの共通語」として確立し、ツールチェーン全体が Rust で書き直され、速度問題も解決されつつある。
第 1 部 — Python 3.13: 言語の未来
1.1 Free-threading (No-GIL) — PEP 703
30 年来の GIL (Global Interpreter Lock) を取り除く Experimental Build が登場 (2024/10):
python3.13t # free-threaded build
- GIL: 一度に 1 スレッドのみ Python バイトコードを実行
- No-GIL: 真のマルチコア並列性
制限: 現状は実験的、シングルスレッド性能は〜10% 低下、C 拡張との互換性問題。2026〜2027 年に安定化予定。
1.2 JIT Compiler — PEP 744
Copy-and-Patch JIT を追加 (実験):
python --enable-experimental-jit
初期ベンチは微小 (〜5%) だが、長期的には PyPy 級の性能が期待される。
1.3 改善された REPL
3.13 の標準 REPL がついに実用レベル:
- 複数行編集
- 構文ハイライト
- ペーストモード
- ブロック履歴
PyPy・ipython に頼っていた機能が標準搭載。
1.4 型システム改善 (3.12〜3.13)
# PEP 695: Generic Syntax
def first[T](items: list[T]) -> T:
return items[0]
class Stack[T]:
def __init__(self) -> None:
self.items: list[T] = []
# PEP 696: Type Parameter Defaults
def process[T = str](x: T) -> T: ...
# PEP 742: TypeIs
from typing import TypeIs
def is_str(x: object) -> TypeIs[str]:
return isinstance(x, str)
第 2 部 — uv: パッケージマネージャ革命
2.1 なぜ uv がゲームチェンジャーか
Astral (Ruff 制作元) が作った Rust 製統合ツール。置き換え対象:
- pip → インストール
- pip-tools → ハッシュ pinned requirements
- pyenv → Python バージョン管理
- virtualenv/venv → 仮想環境
- poetry → プロジェクト管理
- pipx → CLI ツールインストール
速度: pip install が 10 秒かかるプロジェクトも uv なら 0.1 秒。
2.2 基本的な使い方
# インストール
curl -LsSf https://astral.sh/uv/install.sh | sh
# プロジェクト初期化
uv init my-app
cd my-app
# 依存追加 (pyproject.toml 自動更新)
uv add fastapi uvicorn
uv add --dev pytest ruff mypy
# 実行
uv run python main.py
uv run pytest
# Python バージョン管理
uv python install 3.13
uv python pin 3.13
# Lock ファイル (uv.lock)
uv lock
uv sync
2.3 uv script (単一ファイル Python)
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "httpx",
# "rich",
# ]
# ///
import httpx
from rich import print
print(httpx.get("https://api.github.com").json())
uv run script.py
# 依存を自動ダウンロード後に実行
2025 年、新規プロジェクトは uv で始めるのが標準。
第 3 部 — Pydantic v2: 型ベースの検証
3.1 v2 の革命
pydantic-coreを Rust で書き直し- 5〜50 倍高速
Annotatedベースの強力な制約- Serialization API の分離
3.2 基本的な使い方
from pydantic import BaseModel, EmailStr, Field
from typing import Annotated
from datetime import datetime
class User(BaseModel):
id: int
email: EmailStr
name: Annotated[str, Field(min_length=1, max_length=100)]
age: Annotated[int, Field(ge=0, le=150)]
created_at: datetime
# 検証 + 変換
user = User.model_validate({
"id": 1,
"email": "alice@example.com",
"name": "Alice",
"age": 30,
"created_at": "2025-01-01T00:00:00Z"
})
# 直列化
json_str = user.model_dump_json()
dict_data = user.model_dump()
3.3 高度な機能
from pydantic import field_validator, model_validator
class Post(BaseModel):
title: str
content: str
tags: list[str] = []
@field_validator('title')
@classmethod
def title_not_empty(cls, v: str) -> str:
if not v.strip():
raise ValueError('title cannot be empty')
return v.strip()
@model_validator(mode='after')
def check_tags_limit(self) -> 'Post':
if len(self.tags) > 10:
raise ValueError('too many tags')
return self
3.4 Pydantic Settings
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str
api_key: str
debug: bool = False
class Config:
env_file = ".env"
settings = Settings()
環境変数・config 管理の標準。
第 4 部 — FastAPI: 型安全 API の標準
4.1 基本例
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
app = FastAPI()
class UserCreate(BaseModel):
email: str
password: str
class UserResponse(BaseModel):
id: int
email: str
@app.post("/users", response_model=UserResponse)
async def create_user(user: UserCreate) -> UserResponse:
# user はすでに検証済み
# レスポンスは UserResponse として自動直列化
return UserResponse(id=1, email=user.email)
- Pydantic モデルがリクエスト・レスポンススキーマ
- OpenAPI 自動生成 (
/docs) - Dependency Injection 組み込み
4.2 Dependency Injection
async def get_db() -> AsyncGenerator[AsyncSession, None]:
async with async_session() as session:
yield session
async def get_current_user(token: str = Header(...)) -> User:
# トークン検証
return user
@app.get("/me")
async def me(user: User = Depends(get_current_user)) -> UserResponse:
return user
4.3 2025 年の FastAPI スタック
| 目的 | ライブラリ |
|---|---|
| Web | FastAPI |
| ORM | SQLAlchemy 2.0 (async), SQLModel |
| DB ドライバ | asyncpg (Postgres), motor (Mongo) |
| Migration | Alembic |
| Queue | Dramatiq, Celery 5.x, Taskiq |
| Cache | Redis + aioredis |
| Test | pytest + httpx |
| Observability | OpenTelemetry + Prometheus |
第 5 部 — AsyncIO 実戦
5.1 基本構造
import asyncio
async def fetch(url: str) -> str:
# シミュレーション
await asyncio.sleep(1)
return f"data from {url}"
async def main() -> None:
# 逐次
r1 = await fetch("a")
r2 = await fetch("b")
# 同時 (2 倍高速)
r1, r2 = await asyncio.gather(fetch("a"), fetch("b"))
asyncio.run(main())
5.2 TaskGroup (Python 3.11+)
async def main():
async with asyncio.TaskGroup() as tg:
t1 = tg.create_task(fetch("a"))
t2 = tg.create_task(fetch("b"))
t3 = tg.create_task(fetch("c"))
# Context Manager を抜けると全 task 完了
# いずれか例外なら残りはキャンセル + ExceptionGroup
print(t1.result(), t2.result(), t3.result())
TaskGroup は asyncio.gather より優れる: 構造化並行性、自動キャンセル、明確なエラー。
5.3 asyncio.timeout (Python 3.11+)
async def fetch_with_timeout():
async with asyncio.timeout(5.0):
return await slow_operation()
5.4 AsyncIO の落とし穴 5 選
- ブロッキングコードの混在:
requests.getではなくhttpx.AsyncClient asyncio.runのネスト: イベントループ衝突。nest_asyncioはアンチパターン- task 参照の保持失敗:
asyncio.create_taskの結果を保持しないと GC される - CPU バウンド処理:
run_in_executorで別スレッド・プロセスへ async def内のtime.sleep:asyncio.sleepを使うこと
第 6 部 — Polars: 2025 年の Pandas 代替
6.1 なぜ Polars か
| 項目 | Pandas | Polars |
|---|---|---|
| エンジン | NumPy (C) | Rust + Arrow |
| 速度 | 基準 | 5〜100 倍高速 |
| メモリ | 多い | Pandas の〜50% |
| 並列性 | ほぼなし | 自動マルチスレッド |
| Lazy 実行 | × | ○ (オプティマイザ) |
| 大規模データ | 難 | ストリーミング可 |
6.2 基本的な使い方
import polars as pl
df = pl.read_csv("data.csv")
result = (
df
.filter(pl.col("age") > 30)
.group_by("country")
.agg([
pl.col("salary").mean().alias("avg_salary"),
pl.col("id").count().alias("count"),
])
.sort("avg_salary", descending=True)
)
6.3 Lazy Evaluation
lazy_df = pl.scan_csv("huge.csv") # 実際には読まない
result = (
lazy_df
.filter(pl.col("year") == 2024)
.group_by("category")
.agg(pl.col("amount").sum())
.collect() # ここで実行 (オプティマイザが計画)
)
クエリオプティマイザが SQL DBMS のように実行計画を最適化。
6.4 2025 年の移行ガイド
- 新規: Polars をデフォルトに
- 既存 Pandas プロジェクト: 段階移行 (
df.to_pandas()ブリッジ) - 可視化は Pandas の方が楽なことも (matplotlib/seaborn)
- ML ライブラリ互換は依然 Pandas 優位 (改善中)
第 7 部 — 2025 年の AI エンジニアリングスタック
7.1 LangChain の現在
LangChain は 2023 年に爆発、2024 年に成長痛、2025 年は LangGraph 中心に再編。
- LangChain Core: 基本抽象 (Runnable)
- LangGraph: 状態ベースのエージェントグラフ (2025 標準)
- LangSmith: 観測性・評価
7.2 LangGraph 例
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
class State(TypedDict):
messages: Annotated[list, operator.add]
def agent(state: State):
response = llm.invoke(state["messages"])
return {"messages": [response]}
def should_continue(state: State) -> str:
last = state["messages"][-1]
if last.tool_calls:
return "tools"
return END
workflow = StateGraph(State)
workflow.add_node("agent", agent)
workflow.add_node("tools", tool_node)
workflow.set_entry_point("agent")
workflow.add_conditional_edges("agent", should_continue)
workflow.add_edge("tools", "agent")
app = workflow.compile()
Directed Graph + 状態マシンモデル。複雑なエージェントフローに最適。
7.3 Pydantic AI (2024〜)
Pydantic チームによる型安全エージェントフレームワーク。軽量で直感的。
from pydantic_ai import Agent
from pydantic import BaseModel
class WeatherResponse(BaseModel):
city: str
temp_c: float
condition: str
agent = Agent(
'openai:gpt-4o',
result_type=WeatherResponse,
system_prompt='You are a weather assistant.',
)
result = await agent.run('Weather in Seoul?')
print(result.data) # WeatherResponse 型
7.4 2025 年 AI スタック推奨
| 状況 | 推奨 |
|---|---|
| 複雑なマルチステップエージェント | LangGraph |
| シンプルな型安全エージェント | Pydantic AI |
| RAG 特化 | LlamaIndex |
| 本番・最小依存 | OpenAI SDK 直 |
| TS チームとの連携 | Vercel AI SDK (TS) |
第 8 部 — モダン Python 開発環境
8.1 2025 年標準ツールチェーン
# pyproject.toml
[project]
name = "my-app"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.115",
"pydantic>=2.9",
"uvicorn>=0.30",
]
[dependency-groups]
dev = [
"pytest>=8",
"ruff>=0.7",
"mypy>=1.13",
]
[tool.ruff]
line-length = 100
[tool.ruff.lint]
select = ["E", "F", "I", "N", "UP", "B", "S", "C4", "PL"]
[tool.mypy]
strict = true
8.2 Ruff — 10〜100 倍高速 Linter/Formatter
- Flake8, Black, isort, pyupgrade, pylint を置き換え
- Rust 製
- 800+ ルール内蔵
8.3 型チェッカーの選択
| ツール | 特徴 |
|---|---|
| mypy | 最古、遅い、保守的 |
| pyright | MS 製、速い、厳格 |
| pyre | Meta 製、サーバモード |
| ty | Astral 製 (2025)、Rust 製 (開発中) |
2025 年推奨: 新規は pyright、既存は mypy 維持。ty リリース待ち。
8.4 テスト
# pytest + httpx for FastAPI
import pytest
from httpx import AsyncClient, ASGITransport
from myapp.main import app
@pytest.mark.asyncio
async def test_create_user():
async with AsyncClient(
transport=ASGITransport(app=app), base_url="http://test"
) as ac:
r = await ac.post("/users", json={"email": "a@b.com", "password": "pw"})
assert r.status_code == 200
第 9 部 — Python が光る分野と光らない分野
9.1 光る
- AI/ML: PyTorch, JAX, scikit-learn, Hugging Face
- データエンジニアリング: Airflow, dbt, Dagster
- API サーバ: FastAPI の生産性
- 科学計算: NumPy, SciPy
- スクリプト・自動化: グルー言語
- 教育: 学習曲線が緩やか
9.2 光らない
- CPU バウンド高性能: Rust/Go/C++
- モバイルアプリ: Swift/Kotlin
- 組込: C/Rust
- ゲームエンジン: C++
- ブラウザ: JS/TS (Pyodide は特殊用途)
2025 年の現実: Python は「AI・データ・API」の標準だが、「すべてのための言語」ではない。
第 10 部 — 6 ヶ月 Python マスターロードマップ
Month 1: 3.13 基礎
- Type Hints 完全理解 (PEP 695, Union, Literal, Protocol)
- uv でプロジェクト管理
- Ruff + mypy/pyright 設定
Month 2: Pydantic + FastAPI
- Pydantic v2 深化 (Annotated, Validators)
- FastAPI 実戦 API 構築
- Dependency Injection パターン
Month 3: AsyncIO
- TaskGroup, asyncio.timeout
- httpx・asyncpg での非同期 DB
- 並行度制限 (Semaphore)
Month 4: データ処理
- Polars マスター
- SQL + SQLAlchemy 2.0 async
- DuckDB + Parquet
Month 5: AI エンジニアリング
- OpenAI/Anthropic SDK
- LangGraph or Pydantic AI
- Vector DB (Qdrant, Pinecone, pgvector)
- RAG パイプライン構築
Month 6: 運用
- Docker + Kubernetes デプロイ
- 観測性 (OpenTelemetry, Prometheus)
- CI/CD (GitHub Actions)
- プロファイリング (py-spy, scalene)
第 11 部 — Python チェックリスト 12
- uv が置き換える 4 ツール (pip/poetry/pyenv/pip-tools) を知る
- Pydantic v1 vs v2 の主要変更点を知る
- FastAPI Dependency Injection の使い方を知る
- TaskGroup vs asyncio.gather の違いを知る
- Polars Lazy Evaluation の利点を知る
- Type Hints の Protocol, TypeIs の使い方を知る
- SQLAlchemy 2.0 async スタイルを知る
- GIL と Free-threading の意味を知る
- LangGraph と LangChain の関係を知る
- Ruff が置き換えるツール群を知る
- Pydantic Settings で config 管理ができる
- pytest + httpx で async API テストを書ける
第 12 部 — Python アンチパターン 10
pip install+requirements.txtのみ: 再現性が弱い。uv+uv.lockを使う- Type Hints なしで Python を書く: mypy/pyright で捕まえられるバグを放置
from X import *: 名前空間汚染print()でデバッグ:loggingまたはrichexcept Exception: pass: 静かに失敗。具体的な例外 + ログ- ミュータブルなデフォルト引数:
def f(x=[]):は共有される。x=Noneにしてx or [] - Pandas の
iterrows: 遅い。ベクトル演算または Polars - async 関数で sync ライブラリ: イベントループを止める
os.pathではなくpathlibを使わない: pathlib の方がずっと綺麗- Docker イメージ内の
pip install -r requirements.txt: layer caching が壊れる。uv sync --frozen
おわりに — Python は AI 時代に生まれ変わった
Python の本来の強みは「生産性と学習曲線」。弱みは「速度と並行性」だった。
2024〜2025:
- 速度: uv・Pydantic・Polars・Ruff が Rust エンジンで解決
- 並行性: Free-threading 実験、AsyncIO 成熟
- 型: 3.12〜3.13 の PEP で強化
- エコシステム: AI エンジニアリングの標準言語
「Python は遅い」は 2020 年までの話。2025 年の Python は **「AI 時代の共通語であり、Rust ツールで高速化された言語」**だ。
シニアエンジニアが Python を扱わない理由はない。AI・データ・API・スクリプトで Python は今も、そしてこれからも支配的だ。
次回予告 — 「LLM 完全ガイド: Transformer・Attention・RLHF・RAG・Agent・Evaluation」
Season 2 Ep 6 は 2025 年エンジニアの教養、LLM の内部構造。次回:
- Transformer が実際どう動くか
- Attention メカニズムを数式まで
- Pre-training → SFT → RLHF → DPO の流れ
- RAG の 3 世代進化 (Naive → Advanced → Agentic)
- Agent 設計 (ReAct, Plan-and-Execute, Multi-Agent)
- LLM 評価の真の難しさ (LM-as-a-Judge の限界)
ブラックボックスを開ける時間、次回へ続く。
현재 단락 (1/346)
10 年前に Python を学んで戻ってきた人が最も驚く変化: