Python Patterns

affaan-m/ECC/.kiro/skills/python-patterns

作者 affaan-mef648e01899ba3e8dc6371642deaaf64b4477775无许可证275K 个星标收录于 2026年10月9日更新于 2026年10月9日仓库4天前更新

Python-specific design patterns and best practices including protocols, dataclasses, context managers, decorators, async/await, type hints, and package organization. Use when working with Python code to apply Pythonic patterns.

AI 生成的概览

提供 Python 惯用设计模式、类型提示、异步与包组织方式的参考指南,用于编写 Python 代码。

功能
提供 Python 专属设计模式与惯用写法的参考,涵盖基于 Protocol 的鸭子类型、dataclass、上下文管理器、生成器、装饰器、async/await、高级类型提示、依赖注入、包结构、错误处理、属性以及函数式组合。每种模式都配有简短代码示例和优点说明。它产出的是指导内容,而非文件或可运行结果。
适用场景
适用于设计 Python API、包或项目结构,实现异步或并发系统,编写类型安全或符合 Python 风格的代码,或重构现有 Python 代码库时。
运行要求
无需任何工具、软件包或凭据;该技能仅包含说明,不含脚本。示例涉及 typing、dataclasses、contextlib、functools、asyncio 等标准库模块。

Python Patterns

This skill provides comprehensive Python patterns extending common design principles with Python-specific idioms.

Protocol (Duck Typing)

Use Protocol for structural subtyping (duck typing with type hints):

python
from typing import Protocol
class Repository(Protocol):    def find_by_id(self, id: str) -> dict | None: ...    def save(self, entity: dict) -> dict: ...
# Any class with these methods satisfies the protocolclass UserRepository:    def find_by_id(self, id: str) -> dict | None:        # implementation        pass
    def save(self, entity: dict) -> dict:        # implementation        pass
def process_entity(repo: Repository, id: str) -> None:    entity = repo.find_by_id(id)    # ... process

Benefits:

  • Type safety without inheritance
  • Flexible, loosely coupled code
  • Easy testing and mocking

Dataclasses as DTOs

Use dataclass for data transfer objects and value objects:

python
from dataclasses import dataclass, fieldfrom typing import Optional
@dataclassclass CreateUserRequest:    name: str    email: str    age: Optional[int] = None    tags: list[str] = field(default_factory=list)
@dataclass(frozen=True)class User:    """Immutable user entity"""    id: str    name: str    email: str

Features:

  • Auto-generated __init__, __repr__, __eq__
  • frozen=True for immutability
  • field() for complex defaults
  • Type hints for validation

Context Managers

Use context managers (with statement) for resource management:

python
from contextlib import contextmanagerfrom typing import Generator
@contextmanagerdef database_transaction(db) -> Generator[None, None, None]:    """Context manager for database transactions"""    try:        yield        db.commit()    except Exception:        db.rollback()        raise
# Usagewith database_transaction(db):    db.execute("INSERT INTO users ...")

Class-based context manager:

python
class FileProcessor:    def __init__(self, filename: str):        self.filename = filename        self.file = None
    def __enter__(self):        self.file = open(self.filename, 'r')        return self.file
    def __exit__(self, exc_type, exc_val, exc_tb):        if self.file:            self.file.close()        return False  # Don't suppress exceptions

Generators

Use generators for lazy evaluation and memory-efficient iteration:

python
def read_large_file(filename: str):    """Generator for reading large files line by line"""    with open(filename, 'r') as f:        for line in f:            yield line.strip()
# Memory-efficient processingfor line in read_large_file('huge.txt'):    process(line)

Generator expressions:

python
# Instead of list comprehensionsquares = (x**2 for x in range(1000000))  # Lazy evaluation
# Pipeline patternnumbers = (x for x in range(100))evens = (x for x in numbers if x % 2 == 0)squares = (x**2 for x in evens)

Decorators

Function Decorators

python
from functools import wrapsimport time
def timing(func):    """Decorator to measure execution time"""    @wraps(func)    def wrapper(*args, **kwargs):        start = time.time()        result = func(*args, **kwargs)        end = time.time()        print(f"{func.__name__} took {end - start:.2f}s")        return result    return wrapper
@timingdef slow_function():    time.sleep(1)

Class Decorators

python
def singleton(cls):    """Decorator to make a class a singleton"""    instances = {}
    @wraps(cls)    def get_instance(*args, **kwargs):        if cls not in instances:            instances[cls] = cls(*args, **kwargs)        return instances[cls]
    return get_instance
@singletonclass Config:    pass

Async/Await

Async Functions

python
import asynciofrom typing import List
async def fetch_user(user_id: str) -> dict:    """Async function for I/O-bound operations"""    await asyncio.sleep(0.1)  # Simulate network call    return {"id": user_id, "name": "Alice"}
async def fetch_all_users(user_ids: List[str]) -> List[dict]:    """Concurrent execution with asyncio.gather"""    tasks = [fetch_user(uid) for uid in user_ids]    return await asyncio.gather(*tasks)
# Run async codeasyncio.run(fetch_all_users(["1", "2", "3"]))

Async Context Managers

python
class AsyncDatabase:    async def __aenter__(self):        await self.connect()        return self
    async def __aexit__(self, exc_type, exc_val, exc_tb):        await self.disconnect()
async with AsyncDatabase() as db:    await db.query("SELECT * FROM users")

Type Hints

Advanced Type Hints

python
from typing import TypeVar, Generic, Callable, ParamSpec, Concatenate
T = TypeVar('T')P = ParamSpec('P')
class Repository(Generic[T]):    """Generic repository pattern"""    def __init__(self, entity_type: type[T]):        self.entity_type = entity_type
    def find_by_id(self, id: str) -> T | None:        # implementation        pass
# Type-safe decoratordef log_call(func: Callable[P, T]) -> Callable[P, T]:    @wraps(func)    def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:        print(f"Calling {func.__name__}")        return func(*args, **kwargs)    return wrapper

Union Types (Python 3.10+)

python
def process(value: str | int | None) -> str:    match value:        case str():            return value.upper()        case int():            return str(value)        case None:            return "empty"

Dependency Injection

Constructor Injection

python
class UserService:    def __init__(        self,        repository: Repository,        logger: Logger,        cache: Cache | None = None    ):        self.repository = repository        self.logger = logger        self.cache = cache
    def get_user(self, user_id: str) -> User | None:        if self.cache:            cached = self.cache.get(user_id)            if cached:                return cached
        user = self.repository.find_by_id(user_id)        if user and self.cache:            self.cache.set(user_id, user)
        return user

Package Organization

Project Structure

project/├── src/│   └── mypackage/│       ├── __init__.py│       ├── domain/          # Business logic│       │   ├── __init__.py│       │   └── models.py│       ├── services/        # Application services│       │   ├── __init__.py│       │   └── user_service.py│       └── infrastructure/  # External dependencies│           ├── __init__.py│           └── database.py├── tests/│   ├── unit/│   └── integration/├── pyproject.toml└── README.md

Module Exports

python
# __init__.pyfrom .models import User, Productfrom .services import UserService
__all__ = ['User', 'Product', 'UserService']

Error Handling

Custom Exceptions

python
class DomainError(Exception):    """Base exception for domain errors"""    pass
class UserNotFoundError(DomainError):    """Raised when user is not found"""    def __init__(self, user_id: str):        self.user_id = user_id        super().__init__(f"User {user_id} not found")
class ValidationError(DomainError):    """Raised when validation fails"""    def __init__(self, field: str, message: str):        self.field = field        self.message = message        super().__init__(f"{field}: {message}")

Exception Groups (Python 3.11+)

python
try:    # Multiple operations    passexcept* ValueError as eg:    # Handle all ValueError instances    for exc in eg.exceptions:        print(f"ValueError: {exc}")except* TypeError as eg:    # Handle all TypeError instances    for exc in eg.exceptions:        print(f"TypeError: {exc}")

Property Decorators

python
class User:    def __init__(self, name: str):        self._name = name        self._email = None
    @property    def name(self) -> str:        """Read-only property"""        return self._name
    @property    def email(self) -> str | None:        return self._email
    @email.setter    def email(self, value: str) -> None:        if '@' not in value:            raise ValueError("Invalid email")        self._email = value

Functional Programming

Higher-Order Functions

python
from functools import reducefrom typing import Callable, TypeVar
T = TypeVar('T')U = TypeVar('U')
def pipe(*functions: Callable) -> Callable:    """Compose functions left to right"""    def inner(arg):        return reduce(lambda x, f: f(x), functions, arg)    return inner
# Usageprocess = pipe(    str.strip,    str.lower,    lambda s: s.replace(' ', '_'))result = process("  Hello World  ")  # "hello_world"

When to Use This Skill

  • Designing Python APIs and packages
  • Implementing async/concurrent systems
  • Structuring Python projects
  • Writing Pythonic code
  • Refactoring Python codebases
  • Type-safe Python development

来源与署名

来源:affaan-m/ECC位于.kiro/skills/python-patterns提交ef648e0

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架