Smithery Logo
MCPsSkillsDocsPricing
Login
NewFlame, an assistant that learns and improves. Available onTelegramSlack
    affaan-m

    python-patterns

    affaan-m/python-patterns
    Coding
    42,727
    1 installs

    About

    SKILL.md

    Install

    • Telegram
      Telegram
    • Slack
      Slack
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    • Download skill
    ├─
    ├─
    └─
    Smithery Logo

    Give agents more agency

    Resources

    DocumentationPrivacy PolicySystem Status

    Company

    PricingAboutBlog

    Connect

    © 2026 Smithery. All rights reserved.

    About

    Pythonic 惯用法、PEP 8 标准、类型提示以及构建健壮、高效、可维护的 Python 应用程序的最佳实践。

    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 的异步/等待

    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 代码应该具有可读性、显式性,并遵循最小意外原则。如有疑问,优先考虑清晰性而非巧妙性。

    Recommended Servers
    Codeinterpreter
    Codeinterpreter
    Nimble MCP Server
    Nimble MCP Server
    mrc-data
    mrc-data
    Repository
    affaan-m/everything-claude-code
    Files