ECC Python 模式指南:Protocol 鸭子类型、DTO Dataclass 与上下文管理器/生成器的工程化实践
2026/9/10 1:13:03 网站建设 项目流程

ECC Python 模式指南:Protocol 鸭子类型、DTO Dataclass 与上下文管理器/生成器的工程化实践

【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC

本文基于 ECC 仓库 docs/ja-JP/rules/python/patterns.md(及其英文源 rules/python/patterns.md)展开。该规则文件是 ECC 规则体系中对 Python 代码的强制模式约束,用于 Claude Code、Codex、Opencode、Cursor 等 Agent 在编写或评审 Python 代码时遵循统一的工程范式。读完本文,你将掌握三类核心模式——Protocol 鸭子类型、Dataclass 作为 DTO、上下文管理器与生成器——并能结合仓库源码理解这些模式在真实项目中的落地形态。

一、规则文件的定位:面向 Agent 的 Python 模式契约

docs/ja-JP/rules/python/patterns.md是 ECC 规则目录rules/python/下的核心文件之一,其 front-matter 声明了该规则适用的文件路径:

paths: - "**/*.py" - "**/*.pyi"

这意味着任何.py/.pyi文件都在该规则约束范围内。文件开头的说明明确指出,它是对 rules/common/patterns.md(通用模式)的 Python 专属扩展。通用模式文件定义了仓库模式(Repository Pattern,统一封装数据访问接口:findAll、findById、create、update、delete)、骨架项目选取流程、API 响应信封格式等跨语言约定;而 Python 规则文件则在此基础上补充了三个 Python 特有的核心主题:

  1. Protocol(鸭子类型)—— 用结构化子类型代替显式继承;
  2. Dataclass 作为 DTO—— 用数据类承载传输对象;
  3. 上下文管理器与生成器—— 资源管理与惰性迭代。

这四个主题也正是 skills/python-patterns/SKILL.md 技能文件中"Python 开发模式"的浓缩版,规则文件与技能文件互为表里:规则约束 Agent 的行为,技能提供完整知识库。

二、Protocol(鸭子类型):面向接口而非继承

规则文件给出的最小可运行示例:

from typing import Protocol class Repository(Protocol): def find_by_id(self, id: str) -> dict | None: ... def save(self, entity: dict) -> dict: ...

2.1 Protocol 解决什么问题

在 Python 中,传统上"接口"通过abc.ABC@abstractmethod实现(显式继承)。Protocol 则提供结构化子类型(structural subtyping):任何类只要拥有匹配的方法签名,即自动满足该协议,无需显式继承——这正是"鸭子类型"(duck typing)的静态化表达。

这一点与 ECC 仓库自身的抽象设计形成有趣对照。查看 src/llm/core/interface.py,可以看到仓库在核心接口上选择了显式的 ABC 继承

class LLMProvider(ABC): provider_type: ProviderType @abstractmethod def generate(self, input: LLMInput) -> LLMOutput: ... @abstractmethod def list_models(self) -> list[ModelInfo]: ... @abstractmethod def validate_config(self) -> bool: ... def supports_tools(self) -> bool: return True def supports_vision(self) -> bool: return False

从源码结构看,仓库对"跨提供商、需要强制契约保障"的场合(如LLMProvider)使用 ABC 强制实现;而对"插件式、松耦合、仅需特定方法存在"的场合(如规则文件中 Repository 这类数据访问抽象),Protocol 是更轻量的选择。两种模式的分工原则可以概括为:

维度abc.ABC+@abstractmethodtyping.Protocol
关联方式显式继承(is-a)结构匹配(duck typing)
强制程度未实现抽象方法则无法实例化仅在类型检查阶段提示
适用场景需要强契约、多态分发的核心接口依赖倒置、依赖注入、可替换实现
运行时成本有继承开销无运行时开销(仅类型检查)

2.2 工程化要点

  • ...(Ellipsis)作为方法体占位,表示"仅声明签名,不实现";
  • 返回值使用dict | None(Python 3.10+ 的联合类型语法,等价于Optional[dict])表达"可能查不到";
  • 配合 rules/common/patterns.md 中的仓库模式:业务逻辑只依赖抽象接口,数据源(数据库、API、文件)可随时替换,mock 测试也因此变得简单——这正是规则文件把 Repository 列为通用模式、又在 Python 侧给出 Protocol 实现的原因。

三、Dataclass 作为 DTO:数据容器的最小成本方案

规则文件给出的 DTO 示例:

from dataclasses import dataclass @dataclass class CreateUserRequest: name: str email: str age: int | None = None

3.1 Dataclass 与 DTO 的契合点

@dataclass自动生成__init____repr____eq__,让"纯粹装数据的类"不再需要手写样板代码。age: int | None = None表示可选字段(缺省为None),配合默认值即可表达"请求中允许省略"的语义。

仓库 src/llm/core/types.py 是 Dataclass 承载数据的典型实例——并且全部使用frozen=True强化不可变性:

@dataclass(frozen=True) class Message: role: Role ... @dataclass(frozen=True) class ToolDefinition: name: str ... @dataclass(frozen=True) class ToolCall: id: str ... @dataclass(frozen=True) class ToolResult: tool_call_id: str ...

3.2 不可变 DTO 与校验

frozen=True使实例在创建后不可修改,天然适合作为跨模块、跨线程传递的 DTO,避免副作用。这呼应了 rules/python/coding-style.md 中的"优先不可变数据结构"约定:

from dataclasses import dataclass @dataclass(frozen=True) class User: name: str email: str

更进一步的校验可在__post_init__中实现(参见 skills/python-patterns/SKILL.md):

@dataclass class CreateUserRequest: name: str email: str age: int | None = None def __post_init__(self): if "@" not in self.email: raise ValueError(f"Invalid email: {self.email}") if self.age is not None and (self.age < 0 or self.age > 150): raise ValueError(f"Invalid age: {self.age}")

DTO 选择速查:轻量纯数据 →@dataclass;需要不可变 →@dataclass(frozen=True);需要紧凑的具名元组语义 →NamedTuple(也具备不可变性);需要复杂校验/序列化 → pydantic(规则文件中未涉及,但技能库与 rules/python/fastapi.md 有进一步说明)。

四、上下文管理器与生成器:资源与内存的优雅之道

规则文件的两条核心纪律:

  • 资源管理使用上下文管理器(with语句)
  • 惰性求值与内存高效的迭代使用生成器

4.1 上下文管理器:with 语句的两种实现

标准库与contextlib提供了开箱即用的资源管理模式:

# 打开文件(推荐) with open("data.txt", "r") as f: content = f.read() # 文件在离开 with 块后自动关闭 # 自定义计时器(contextmanager 装饰器) from contextlib import contextmanager import time @contextmanager def timer(name: str): start = time.perf_counter() yield elapsed = time.perf_counter() - start print(f"{name} took {elapsed:.4f} seconds") with timer("data processing"): process_large_dataset()

对于更复杂的状态(如数据库事务),可用类实现__enter__/__exit__协议,在__exit__中根据是否有异常决定提交或回滚(完整示例见 skills/python-patterns/SKILL.md 的DatabaseTransaction)。

4.2 生成器:惰性求值与内存效率

def read_large_file(path: str): """逐行读取大文件,内存中始终只保留一行。""" with open(path) as f: for line in f: yield line.strip() for line in read_large_file("huge.txt"): process(line)

生成器与yield让"一次性流式处理"成为可能,避免将整个数据集载入内存。配合生成器表达式还能显著降低中间内存占用:

# 推荐:惰性求和,不产生中间 list total = sum(x * x for x in range(1_000_000)) # 不推荐:先生成完整列表再求和 total = sum([x * x for x in range(1_000_000)])

4.3 在 Agent 场景中的意义

ECC 是"agent harness 性能优化系统",其规则要求 Agent 生成的 Python 代码默认遵循这些模式:skills/python-patterns/SKILL.md 中明确把"上下文管理器用于资源管理、生成器用于大数据的惰性求值"列入快速参考表,并在性能小节给出__slots__减少内存占用、join代替循环内字符串拼接(避免 O(n²))等补充纪律。这些约定与 rules/python/testing.md(pytest 框架 +pytest --cov=src --cov-report=term-missing覆盖率门禁)共同构成 Python 代码从编写到验证的完整闭环。

五、规则如何在 ECC 中生效

本规则文件通过 front-matter 的paths声明作用域,与 rules/python/coding-style.md、rules/python/testing.md、rules/python/security.md 等同目录规则配合,由 Agent 在编写/评审**/*.py**/*.pyi文件时自动加载。详细模式(装饰器、并发、包结构、工具链配置等)则由 skills/python-patterns/SKILL.md 技能文件提供,可通过引用技能名python-patterns激活,其description字段声明了适用时机:"writing or reviewing Python code and idiomatic structure, typing, or PEP 8 is in question"。

六、速查表与自检清单

模式一句话规则仓库参考
Protocol用结构化子类型声明接口,替代显式继承rules/python/patterns.md
Dataclass DTO@dataclass承载传输对象,frozen=True增强不可变src/llm/core/types.py
上下文管理器with统一资源获取与释放skills/python-patterns/SKILL.md
生成器yield惰性产出,控制峰值内存skills/python-patterns/SKILL.md

评审或生成 Python 代码时的自检项:

  1. 数据访问抽象是否用 Protocol 声明,业务层是否只依赖接口?
  2. DTO 是否用@dataclass(必要时frozen=True)而非手写样板类?
  3. 文件、锁、连接等资源是否全部走with语句?
  4. 大数据集是否用生成器/生成器表达式避免整载入内存?
  5. 是否遵循 PEP 8 与 rules/python/coding-style.md 的格式化约定(black、isort、ruff)?

【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询