Source profileQuality 77/100

affaan-m/ECC/docs/ja-JP/skills/python-patterns/SKILL.md

python-patterns

Review python-patterns's use cases, installation, workflow, and original source instructions.

Source repository stars
234,327
Declared platforms
0
Static risk flags
2
Last source update
2026-07-27
Source checked
2026-07-28

Decision brief

What it does—and where it fits

堅牢で効率的かつ保守可能なアプリケーションを構築するための慣用的なPythonパターンとベストプラクティス。

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/python-patterns"
    Safe inspection promptEditorial

    Inspect the Agent Skill "python-patterns" from https://github.com/affaan-m/ECC/blob/4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38/docs/ja-JP/skills/python-patterns/SKILL.md at commit 4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Usage

      def getuser(userid: str) - User: user = db.finduser(userid) if not user: raise NotFoundError(f"User not found: {userid}") return user python

      def getuser(userid: str) - User: user = db.finduser(userid) if not user: raise NotFoundError(f"User not found: {userid}") return user python
    2. 02

      Each call to process() prints the call count

      python import concurrent.futures import threading

      python import concurrent.futures import threadingdef fetchurl(url: str) - str: """Fetch a URL (I/O-bound operation).""" import urllib.request with urllib.request.urlopen(url) as response: return response.read().decode()def fetchallurls(urls: list[str]) - dict[str, str]: """Fetch multiple URLs concurrently using threads.""" with concurrent.futures.ThreadPoolExecutor(maxworkers=10) as executor: futuretourl = {executor.submit(fetchurl, u…
    3. 03

      Good: slots reduces memory usage

      class Point: slots = ['x', 'y']

      class Point: slots = ['x', 'y']def init(self, x: float, y: float): self.x = x self.y = y python
    4. 04

      いつ有効化するか

      新しいPythonコードを書くとき

      新しいPythonコードを書くときPythonコードをレビューするとき既存のPythonコードをリファクタリングするとき
    5. 05

      核となる原則

      Pythonは可読性を優先します。コードは明白で理解しやすいものであるべきです。

      Pythonは可読性を優先します。コードは明白で理解しやすいものであるべきです。

    Permission review

    Static risk signals and limitations

    Reads files

    low · line 198

    The documentation asks the agent to read local files, directories, or repositories.

    with open(path, 'r') as f:

    Reads files

    low · line 203

    The documentation asks the agent to read local files, directories, or repositories.

    f = open(path, 'r')

    Network access

    medium · line 443

    The documentation includes network, browsing, or remote request actions.

    """Fetch a URL (I/O-bound operation)."""

    Network access

    medium · line 445

    The documentation includes network, browsing, or remote request actions.

    with urllib.request.urlopen(url) as response:

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score77/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars234,327SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    affaan-m/ECC
    Skill path
    docs/ja-JP/skills/python-patterns/SKILL.md
    Commit
    4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38
    License
    MIT
    Collected
    2026-07-28
    Default branch
    main
    View the original SKILL.md

    Python開発パターン

    堅牢で効率的かつ保守可能なアプリケーションを構築するための慣用的なPythonパターンとベストプラクティス。

    いつ有効化するか

    • 新しいPythonコードを書くとき
    • Pythonコードをレビューするとき
    • 既存のPythonコードをリファクタリングするとき
    • Pythonパッケージ/モジュールを設計するとき

    核となる原則

    1. 可読性が重要

    Pythonは可読性を優先します。コードは明白で理解しやすいものであるべきです。

    # Good: Clear and readable
    def get_active_users(users: list[User]) -> list[User]:
        """Return only active users from the provided list."""
        return [user for user in users if user.is_active]
    
    
    # Bad: Clever but confusing
    def get_active_users(u):
        return [x for x in u if x.a]
    

    2. 明示的は暗黙的より良い

    魔法を避け、コードが何をしているかを明確にしましょう。

    # Good: Explicit configuration
    import logging
    
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    
    # Bad: Hidden side effects
    import some_module
    some_module.setup()  # What does this do?
    

    3. EAFP - 許可を求めるより許しを請う方が簡単

    Pythonは条件チェックよりも例外処理を好みます。

    # Good: EAFP style
    def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
        try:
            return dictionary[key]
        except KeyError:
            return default_value
    
    # Bad: LBYL (Look Before You Leap) style
    def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
        if key in dictionary:
            return dictionary[key]
        else:
            return default_value
    

    型ヒント

    基本的な型アノテーション

    from typing import Optional, List, Dict, Any
    
    def process_user(
        user_id: str,
        data: Dict[str, Any],
        active: bool = True
    ) -> Optional[User]:
        """Process a user and return the updated User or None."""
        if not active:
            return None
        return User(user_id, data)
    

    モダンな型ヒント(Python 3.9+)

    # Python 3.9+ - Use built-in types
    def process_items(items: list[str]) -> dict[str, int]:
        return {item: len(item) for item in items}
    
    # Python 3.8 and earlier - Use typing module
    from typing import List, Dict
    
    def process_items(items: List[str]) -> Dict[str, int]:
        return {item: len(item) for item in items}
    

    型エイリアスとTypeVar

    from typing import TypeVar, Union
    
    # Type alias for complex types
    JSON = Union[dict[str, Any], list[Any], str, int, float, bool, None]
    
    def parse_json(data: str) -> JSON:
        return json.loads(data)
    
    # Generic types
    T = TypeVar('T')
    
    def first(items: list[T]) -> T | None:
        """Return the first item or None if list is empty."""
        return items[0] if items else None
    

    プロトコルベースのダックタイピング

    from typing import Protocol
    
    class Renderable(Protocol):
        def render(self) -> str:
            """Render the object to a string."""
    
    def render_all(items: list[Renderable]) -> str:
        """Render all items that implement the Renderable protocol."""
        return "\n".join(item.render() for item in items)
    

    エラーハンドリングパターン

    特定の例外処理

    # Good: Catch specific exceptions
    def load_config(path: str) -> Config:
        try:
            with open(path) as f:
                return Config.from_json(f.read())
        except FileNotFoundError as e:
            raise ConfigError(f"Config file not found: {path}") from e
        except json.JSONDecodeError as e:
            raise ConfigError(f"Invalid JSON in config: {path}") from e
    
    # Bad: Bare except
    def load_config(path: str) -> Config:
        try:
            with open(path) as f:
                return Config.from_json(f.read())
        except:
            return None  # Silent failure!
    

    例外の連鎖

    def process_data(data: str) -> Result:
        try:
            parsed = json.loads(data)
        except json.JSONDecodeError as e:
            # Chain exceptions to preserve the traceback
            raise ValueError(f"Failed to parse data: {data}") from e
    

    カスタム例外階層

    class AppError(Exception):
        """Base exception for all application errors."""
        pass
    
    class ValidationError(AppError):
        """Raised when input validation fails."""
        pass
    
    class NotFoundError(AppError):
        """Raised when a requested resource is not found."""
        pass
    
    # Usage
    def get_user(user_id: str) -> User:
        user = db.find_user(user_id)
        if not user:
            raise NotFoundError(f"User not found: {user_id}")
        return user
    

    コンテキストマネージャ

    リソース管理

    # Good: Using context managers
    def process_file(path: str) -> str:
        with open(path, 'r') as f:
            return f.read()
    
    # Bad: Manual resource management
    def process_file(path: str) -> str:
        f = open(path, 'r')
        try:
            return f.read()
        finally:
            f.close()
    

    カスタムコンテキストマネージャ

    from contextlib import contextmanager
    
    @contextmanager
    def timer(name: str):
        """Context manager to time a block of code."""
        start = time.perf_counter()
        yield
        elapsed = time.perf_counter() - start
        print(f"{name} took {elapsed:.4f} seconds")
    
    # Usage
    with timer("data processing"):
        process_large_dataset()
    

    コンテキストマネージャクラス

    class DatabaseTransaction:
        def __init__(self, connection):
            self.connection = connection
    
        def __enter__(self):
            self.connection.begin_transaction()
            return self
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            if exc_type is None:
                self.connection.commit()
            else:
                self.connection.rollback()
            return False  # Don't suppress exceptions
    
    # Usage
    with DatabaseTransaction(conn):
        user = conn.create_user(user_data)
        conn.create_profile(user.id, profile_data)
    

    内包表記とジェネレータ

    リスト内包表記

    # Good: List comprehension for simple transformations
    names = [user.name for user in users if user.is_active]
    
    # Bad: Manual loop
    names = []
    for user in users:
        if user.is_active:
            names.append(user.name)
    
    # Complex comprehensions should be expanded
    # Bad: Too complex
    result = [x * 2 for x in items if x > 0 if x % 2 == 0]
    
    # Good: Use a generator function
    def filter_and_transform(items: Iterable[int]) -> list[int]:
        result = []
        for x in items:
            if x > 0 and x % 2 == 0:
                result.append(x * 2)
        return result
    

    ジェネレータ式

    # Good: Generator for lazy evaluation
    total = sum(x * x for x in range(1_000_000))
    
    # Bad: Creates large intermediate list
    total = sum([x * x for x in range(1_000_000)])
    

    ジェネレータ関数

    def read_large_file(path: str) -> Iterator[str]:
        """Read a large file line by line."""
        with open(path) as f:
            for line in f:
                yield line.strip()
    
    # Usage
    for line in read_large_file("huge.txt"):
        process(line)
    

    データクラスと名前付きタプル

    データクラス

    from dataclasses import dataclass, field
    from datetime import datetime
    
    @dataclass
    class User:
        """User entity with automatic __init__, __repr__, and __eq__."""
        id: str
        name: str
        email: str
        created_at: datetime = field(default_factory=datetime.now)
        is_active: bool = True
    
    # Usage
    user = User(
        id="123",
        name="Alice",
        email="alice@example.com"
    )
    

    バリデーション付きデータクラス

    @dataclass
    class User:
        email: str
        age: int
    
        def __post_init__(self):
            # Validate email format
            if "@" not in self.email:
                raise ValueError(f"Invalid email: {self.email}")
            # Validate age range
            if self.age < 0 or self.age > 150:
                raise ValueError(f"Invalid age: {self.age}")
    

    名前付きタプル

    from typing import NamedTuple
    
    class Point(NamedTuple):
        """Immutable 2D point."""
        x: float
        y: float
    
        def distance(self, other: 'Point') -> float:
            return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5
    
    # Usage
    p1 = Point(0, 0)
    p2 = Point(3, 4)
    print(p1.distance(p2))  # 5.0
    

    デコレータ

    関数デコレータ

    import functools
    import time
    
    def timer(func: Callable) -> Callable:
        """Decorator to time function execution."""
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            start = time.perf_counter()
            result = func(*args, **kwargs)
            elapsed = time.perf_counter() - start
            print(f"{func.__name__} took {elapsed:.4f}s")
            return result
        return wrapper
    
    @timer
    def slow_function():
        time.sleep(1)
    
    # slow_function() prints: slow_function took 1.0012s
    

    パラメータ化デコレータ

    def repeat(times: int):
        """Decorator to repeat a function multiple times."""
        def decorator(func: Callable) -> Callable:
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                results = []
                for _ in range(times):
                    results.append(func(*args, **kwargs))
                return results
            return wrapper
        return decorator
    
    @repeat(times=3)
    def greet(name: str) -> str:
        return f"Hello, {name}!"
    
    # greet("Alice") returns ["Hello, Alice!", "Hello, Alice!", "Hello, Alice!"]
    

    クラスベースのデコレータ

    class CountCalls:
        """Decorator that counts how many times a function is called."""
        def __init__(self, func: Callable):
            functools.update_wrapper(self, func)
            self.func = func
            self.count = 0
    
        def __call__(self, *args, **kwargs):
            self.count += 1
            print(f"{self.func.__name__} has been called {self.count} times")
            return self.func(*args, **kwargs)
    
    @CountCalls
    def process():
        pass
    
    # Each call to process() prints the call count
    

    並行処理パターン

    I/Oバウンドタスク用のスレッド

    import concurrent.futures
    import threading
    
    def fetch_url(url: str) -> str:
        """Fetch a URL (I/O-bound operation)."""
        import urllib.request
        with urllib.request.urlopen(url) as response:
            return response.read().decode()
    
    def fetch_all_urls(urls: list[str]) -> dict[str, str]:
        """Fetch multiple URLs concurrently using threads."""
        with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
            future_to_url = {executor.submit(fetch_url, url): url for url in urls}
            results = {}
            for future in concurrent.futures.as_completed(future_to_url):
                url = future_to_url[future]
                try:
                    results[url] = future.result()
                except Exception as e:
                    results[url] = f"Error: {e}"
        return results
    

    CPUバウンドタスク用のマルチプロセシング

    def process_data(data: list[int]) -> int:
        """CPU-intensive computation."""
        return sum(x ** 2 for x in data)
    
    def process_all(datasets: list[list[int]]) -> list[int]:
        """Process multiple datasets using multiple processes."""
        with concurrent.futures.ProcessPoolExecutor() as executor:
            results = list(executor.map(process_data, datasets))
        return results
    

    並行I/O用のAsync/Await

    import asyncio
    
    async def fetch_async(url: str) -> str:
        """Fetch a URL asynchronously."""
        import aiohttp
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                return await response.text()
    
    async def fetch_all(urls: list[str]) -> dict[str, str]:
        """Fetch multiple URLs concurrently."""
        tasks = [fetch_async(url) for url in urls]
        results = await asyncio.gather(*tasks, return_exceptions=True)
        return dict(zip(urls, results))
    

    パッケージ構成

    標準プロジェクトレイアウト

    myproject/
    ├── src/
    │   └── mypackage/
    │       ├── __init__.py
    │       ├── main.py
    │       ├── api/
    │       │   ├── __init__.py
    │       │   └── routes.py
    │       ├── models/
    │       │   ├── __init__.py
    │       │   └── user.py
    │       └── utils/
    │           ├── __init__.py
    │           └── helpers.py
    ├── tests/
    │   ├── __init__.py
    │   ├── conftest.py
    │   ├── test_api.py
    │   └── test_models.py
    ├── pyproject.toml
    ├── README.md
    └── .gitignore
    

    インポート規約

    # Good: Import order - stdlib, third-party, local
    import os
    import sys
    from pathlib import Path
    
    import requests
    from fastapi import FastAPI
    
    from mypackage.models import User
    from mypackage.utils import format_name
    
    # Good: Use isort for automatic import sorting
    # pip install isort
    

    パッケージエクスポート用の__init__.py

    # mypackage/__init__.py
    """mypackage - A sample Python package."""
    
    __version__ = "1.0.0"
    
    # Export main classes/functions at package level
    from mypackage.models import User, Post
    from mypackage.utils import format_name
    
    __all__ = ["User", "Post", "format_name"]
    

    メモリとパフォーマンス

    メモリ効率化のための__slots__使用

    # Bad: Regular class uses __dict__ (more memory)
    class Point:
        def __init__(self, x: float, y: float):
            self.x = x
            self.y = y
    
    # Good: __slots__ reduces memory usage
    class Point:
        __slots__ = ['x', 'y']
    
        def __init__(self, x: float, y: float):
            self.x = x
            self.y = y
    

    大量データ用のジェネレータ

    # Bad: Returns full list in memory
    def read_lines(path: str) -> list[str]:
        with open(path) as f:
            return [line.strip() for line in f]
    
    # Good: Yields lines one at a time
    def read_lines(path: str) -> Iterator[str]:
        with open(path) as f:
            for line in f:
                yield line.strip()
    

    ループ内での文字列連結を避ける

    # Bad: O(n²) due to string immutability
    result = ""
    for item in items:
        result += str(item)
    
    # Good: O(n) using join
    result = "".join(str(item) for item in items)
    
    # Good: Using StringIO for building
    from io import StringIO
    
    buffer = StringIO()
    for item in items:
        buffer.write(str(item))
    result = buffer.getvalue()
    

    Pythonツール統合

    基本コマンド

    # Code formatting
    black .
    isort .
    
    # Linting
    ruff check .
    pylint mypackage/
    
    # Type checking
    mypy .
    
    # Testing
    pytest --cov=mypackage --cov-report=html
    
    # Security scanning
    bandit -r .
    
    # Dependency management
    pip-audit
    safety check
    

    pyproject.toml設定

    [project]
    name = "mypackage"
    version = "1.0.0"
    requires-python = ">=3.9"
    dependencies = [
        "requests>=2.31.0",
        "pydantic>=2.0.0",
    ]
    
    [project.optional-dependencies]
    dev = [
        "pytest>=7.4.0",
        "pytest-cov>=4.1.0",
        "black>=23.0.0",
        "ruff>=0.1.0",
        "mypy>=1.5.0",
    ]
    
    [tool.black]
    line-length = 88
    target-version = ['py39']
    
    [tool.ruff]
    line-length = 88
    select = ["E", "F", "I", "N", "W"]
    
    [tool.mypy]
    python_version = "3.9"
    warn_return_any = true
    warn_unused_configs = true
    disallow_untyped_defs = true
    
    [tool.pytest.ini_options]
    testpaths = ["tests"]
    addopts = "--cov=mypackage --cov-report=term-missing"
    

    クイックリファレンス:Pythonイディオム

    イディオム説明
    EAFP許可を求めるより許しを請う方が簡単
    コンテキストマネージャリソース管理にはwithを使用
    リスト内包表記簡単な変換用
    ジェネレータ遅延評価と大規模データセット用
    型ヒント関数シグネチャへのアノテーション
    データクラス自動生成メソッド付きデータコンテナ用
    __slots__メモリ最適化用
    f-strings文字列フォーマット用(Python 3.6+)
    pathlib.Pathパス操作用(Python 3.4+)
    enumerateループ内のインデックス-要素ペア用

    避けるべきアンチパターン

    # Bad: Mutable default arguments
    def append_to(item, items=[]):
        items.append(item)
        return items
    
    # Good: Use None and create new list
    def append_to(item, items=None):
        if items is None:
            items = []
        items.append(item)
        return items
    
    # Bad: Checking type with type()
    if type(obj) == list:
        process(obj)
    
    # Good: Use isinstance
    if isinstance(obj, list):
        process(obj)
    
    # Bad: Comparing to None with ==
    if value == None:
        process()
    
    # Good: Use is
    if value is None:
        process()
    
    # Bad: from module import *
    from os.path import *
    
    # Good: Explicit imports
    from os.path import join, exists
    
    # Bad: Bare except
    try:
        risky_operation()
    except:
        pass
    
    # Good: Specific exception
    try:
        risky_operation()
    except SpecificError as e:
        logger.error(f"Operation failed: {e}")
    

    覚えておいてください: Pythonコードは読みやすく、明示的で、最小の驚きの原則に従うべきです。迷ったときは、巧妙さよりも明確さを優先してください。

    Alternatives

    Compare before choosing