Source profileQuality 79/100

affaan-m/ECC/docs/zh-CN/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/zh-CN/skills/python-patterns"
    Safe inspection promptEditorial

    Inspect the Agent Skill "python-patterns" from https://github.com/affaan-m/ECC/blob/4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38/docs/zh-CN/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 包/模块

      编写新的 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 score79/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/zh-CN/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 的异步/等待

    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