mcpField
P
python-anti-patterns

python-anti-patterns

github.com/full-stack-skillsテスト・品質395 回インストール4 週間前に更新
リポジトリ

python-anti-patterns について

python-anti-patternsは、Pythonコードのレビュー向けチェックリストです。インフラ、設計、エラー処理、リソース、型、テストを扱い、例と改善案を使ってマージ前やリファクタリング時に問題を見つける手助けをします。

主な機能

  1. 01リトライと設定管理の問題を確認
  2. 02設計とエラー処理のアンチパターンを特定
  3. 03リソース管理と非同期処理のブロッキングを確認
  4. 04型ヒントとテストの境界条件を網羅

活用シーン

  1. 01マージ前にPythonコードをレビューする
  2. 02不適切な実践に起因する可能性のある問題を調べる
  3. 03レガシーコードを改修し、チーム規約を整える
  4. 04Pythonのよくある誤りと修正方法を学ぶ

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/full-stack-skills/python-skills --skill python-anti-patterns

インストール後、Claude Code で/python-anti-patternsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE.txt
agents/
openai.yaml
examples/
advanced-usage.md
basic-usage.md
integration.md

詳細

出典に関する声明:wshobson/agents を基にしたスキル内容です
(MIT License, Copyright (c) 2024 Seth Hobson;ライセンス全文は同じディレクトリ内の LICENSE.txt をご覧ください)。
使用、変更、再配布にあたっては、当該 MIT ライセンスの条項に従い、著作権表示を保持する必要があります。

中国語の説明

このスキルでは、フルスタック開発に関するベストプラクティスとパターンを案内します。


name: python-anti-patterns description: よくあるアンチパターンを避けるために Python コードをレビューするときに、このスキルを使用します。コードレビュー時、実装を仕上げる前、または既知の悪いプラクティスに起因する可能性のある問題をデバッグするときのチェックリストとして使用してください。

Python アンチパターンチェックリスト

Python コードでよく見られる間違いやアンチパターンをまとめた参照用チェックリストです。実装を仕上げる前に確認し、問題を早期に発見してください。

このスキルを使用する場面

  • マージ前のコードレビュー
  • 原因不明の問題のデバッグ
  • Python のベストプラクティスの指導や学習
  • チームのコーディング規約の策定
  • レガシーコードのリファクタリング

**注:**このスキルでは避けるべきことに焦点を当てています。望ましいパターンやアーキテクチャについては、python-design-patterns スキルを参照してください。

インフラストラクチャのアンチパターン

タイムアウト/リトライロジックの分散
# BAD: Timeout logic duplicated everywhere
def fetch_user(user_id):
    try:
        return requests.get(url, timeout=30)
    except Timeout:
        logger.warning("Timeout fetching user")
        return None

def fetch_orders(user_id):
    try:
        return requests.get(url, timeout=30)
    except Timeout:
        logger.warning("Timeout fetching orders")
        return None

**修正方法:**デコレーターまたはクライアントラッパーに集約します。

# GOOD: Centralized retry logic
@retry(stop=stop_after_attempt(3), wait=wait_exponential())
def http_get(url: str) -> Response:
    return requests.get(url, timeout=30)
二重リトライ
# BAD: Retrying at multiple layers
@retry(max_attempts=3)  # Application retry
def call_service():
    return client.request()  # Client also has retry configured!

**修正方法:**リトライは単一のレイヤーでのみ行います。インフラストラクチャのリトライ動作を把握してください。

ハードコードされた設定
# BAD: Secrets and config in code
DB_HOST = "prod-db.example.com"
API_KEY = "sk-12345"

def connect():
    return psycopg.connect(f"host={DB_HOST}...")

**修正方法:**型付きの設定で環境変数を使用します。

# GOOD
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    db_host: str = Field(alias="DB_HOST")
    api_key: str = Field(alias="API_KEY")

settings = Settings()

アーキテクチャのアンチパターン

内部型の公開
# BAD: Leaking ORM model to API
@app.get("/users/{id}")
def get_user(id: str) -> UserModel:  # SQLAlchemy model
    return db.query(UserModel).get(id)

**修正方法:**DTO/レスポンスモデルを使用します。

# GOOD
@app.get("/users/{id}")
def get_user(id: str) -> UserResponse:
    user = db.query(UserModel).get(id)
    return UserResponse.from_orm(user)
I/O とビジネスロジックの混在
# BAD: SQL embedded in business logic
def calculate_discount(user_id: str) -> float:
    user = db.query("SELECT * FROM users WHERE id = ?", user_id)
    orders = db.query("SELECT * FROM orders WHERE user_id = ?", user_id)
    # Business logic mixed with data access
    if len(orders) > 10:
        return 0.15
    return 0.0

**修正方法:**リポジトリパターンを使用します。ビジネスロジックは純粋な状態に保ちます。

# GOOD
def calculate_discount(user: User, orders: list[Order]) -> float:
    # Pure business logic, easily testable
    if len(orders) > 10:
        return 0.15
    return 0.0

エラー処理のアンチパターン

例外の無差別な処理
# BAD: Swallowing all exceptions
try:
    process()
except Exception:
    pass  # Silent failure - bugs hidden forever

**修正方法:**特定の例外を捕捉し、適切にログ記録または処理します。

# GOOD
try:
    process()
except ConnectionError as e:
    logger.warning("Connection failed, will retry", error=str(e))
    raise
except ValueError as e:
    logger.error("Invalid input", error=str(e))
    raise BadRequestError(str(e))
部分的な失敗の無視
# BAD: Stops on first error
def process_batch(items):
    results = []
    for item in items:
        result = process(item)  # Raises on error - batch aborted
        results.append(result)
    return results

**修正方法:**成功と失敗の両方を記録します。

# GOOD
def process_batch(items) -> BatchResult:
    succeeded = {}
    failed = {}
    for idx, item in enumerate(items):
        try:
            succeeded[idx] = process(item)
        except Exception as e:
            failed[idx] = e
    return BatchResult(succeeded, failed)
入力検証の欠如
# BAD: No validation
def create_user(data: dict):
    return User(**data)  # Crashes deep in code on bad input

**修正方法:**API 境界で早期に検証します。

# GOOD
def create_user(data: dict) -> User:
    validated = CreateUserInput.model_validate(data)
    return User.from_input(validated)

リソースのアンチパターン

リソースを閉じない
# BAD: File never closed
def read_file(path):
    f = open(path)
    return f.read()  # What if this raises?

**修正方法:**コンテキストマネージャーを使用します。

# GOOD
def read_file(path):
    with open(path) as f:
        return f.read()
非同期処理内でのブロッキング
# BAD: Blocks the entire event loop
async def fetch_data():
    time.sleep(1)  # Blocks everything!
    response = requests.get(url)  # Also blocks!

**修正方法:**非同期処理にネイティブ対応したライブラリを使用します。

# GOOD
async def fetch_data():
    await asyncio.sleep(1)
    async with httpx.AsyncClient() as client:
        response = await client.get(url)

型安全性のアンチパターン

型ヒントの欠如
# BAD: No types
def process(data):
    return data["value"] * 2

**修正方法:**すべての公開関数に型注釈を付けます。

# GOOD
def process(data: dict[str, int]) -> int:
    return data["value"] * 2
型指定のないコレクション
# BAD: Generic list without type parameter
def get_users() -> list:
    ...

**修正方法:**型パラメーターを使用します。

# GOOD
def get_users() -> list[User]:
    ...

テストのアンチパターン

正常系のみのテスト
# BAD: Only tests success case
def test_create_user():
    user = service.create_user(valid_data)
    assert user.id is not None

**修正方法:**エラー条件とエッジケースをテストします。

# GOOD
def test_create_user_success():
    user = service.create_user(valid_data)
    assert user.id is not None

def test_create_user_invalid_email():
    with pytest.raises(ValueError, match="Invalid email"):
        service.create_user(invalid_email_data)

def test_create_user_duplicate_email():
    service.create_user(valid_data)
    with pytest.raises(ConflictError):
        service.create_user(valid_data)
過剰なモック
# BAD: Mocking everything
def test_user_service():
    mock_repo = Mock()
    mock_cache = Mock()
    mock_logger = Mock()
    mock_metrics = Mock()
    # Test doesn't verify real behavior

**修正方法:**重要な処理経路には統合テストを使用します。モックは外部サービスに限定します。

簡易レビュー用チェックリスト

コードを仕上げる前に、以下を確認します。

  • タイムアウト/リトライロジックが分散していない(集約されている)
  • 二重リトライがない(アプリケーション+インフラストラクチャ)
  • 設定やシークレットがハードコードされていない
  • 内部型(ORM モデル、protobuf)が公開されていない
  • I/O とビジネスロジックが混在していない
  • except Exception: pass のような無差別な例外処理がない
  • バッチ処理で部分的な失敗が無視されていない
  • 入力検証が欠けていない
  • リソースが閉じられている(コンテキストマネージャーを使用)
  • 非同期コード内にブロッキング呼び出しがない
  • すべての公開関数に型ヒントがある
  • コレクションに型パラメーターがある
  • エラー経路がテストされている
  • エッジケースがカバーされている

よくある修正方法のまとめ

アンチパターン修正方法
リトライロジックの分散デコレーターに集約
ハードコードされた設定環境変数+pydantic-settings
ORM モデルの公開DTO/レスポンススキーマ
I/O とロジックの混在リポジトリパターン
無差別な例外処理特定の例外を捕捉
エラー時にバッチが停止する成功と失敗を含む BatchResult を返す
検証がないPydantic を使って境界で検証
リソースを閉じないコンテキストマネージャー
非同期処理内でのブロッキング非同期処理にネイティブ対応したライブラリ
型指定の欠如すべての公開 API に型注釈を付ける
正常系のみのテストエラーとエッジケースをテスト

能力の範囲

✅ 得意なこと
  • フルスタック開発に関するベストプラクティス
  • コードアーキテクチャの設計ガイダンス
  • パフォーマンス最適化の提案
⚠️ 必要な情報
  • 具体的なプロジェクトのコンテキスト
  • 技術スタックの情報
❌ 対象外
  • 技術以外の分野におけるビジネス上の意思決定
  • 具体的なコードの実装(ガイダンスのみを提供)

ワークフロー

Step 1: 需求分析

理解项目需求和技术约束

Step 2: 架构设计

设计系统架构和组件划分

Step 3: 实现指导

提供具体的实现建议和代码模式

Step 4: 代码审查

审查代码质量和最佳实践遵循情况

Step 5: 优化建议

提供性能优化和改进建议

Gotchas

1. 过度设计

避免在简单场景中使用复杂的设计模式

2. 性能忽视

不要忽视性能优化,特别是在生产环境中

3. 安全考虑

始终考虑安全性和数据保护

4. 测试覆盖

确保有足够的测试覆盖,特别是边界情况

5. 文档维护

保持文档与代码同步更新

コメント