You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pydantic模型中排除字段以避免__eq__递归错误?

解决Pydantic模型循环引用导致的递归比较栈溢出问题

核心原因

list.remove()方法会调用对象的__eq__进行相等性判断,而Pydantic默认的__eq__会递归比较所有字段。当模型存在循环引用(如previous_model互相指向)时,递归比较会触发RecursionError。

解决方案:重写__eq__方法排除指定字段

直接在SomeModel中重写__eq__方法,只比较需要的字段(name和content),忽略previous_model:

Pydantic v1 代码示例

import typing
import pydantic

class SomeModel(pydantic.BaseModel):
    name: str
    content: str
    previous_model: typing.Optional["SomeModel"] = None

    def __eq__(self, other):
        if not isinstance(other, SomeModel):
            return False
        # 只比较name和content字段
        return self.name == other.name and self.content == other.content

# 测试代码
models = [
   SomeModel(name="bob", content="2"),
   SomeModel(name="bob", content="2"),
]
models[0].previous_model = models[1]
models[1].previous_model = models[0]

models.remove(models[0])  # 现在不会触发递归错误

Pydantic v2 代码示例

如果使用Pydantic v2,写法类似,只是导入路径略有不同:

import typing
from pydantic import BaseModel

class SomeModel(BaseModel):
    name: str
    content: str
    previous_model: typing.Optional["SomeModel"] = None

    def __eq__(self, other: object) -> bool:
        if not isinstance(other, SomeModel):
            return False
        return self.name == other.name and self.content == other.content

补充说明

  • 重写__eq__时,先判断other的类型,避免和非SomeModel对象比较出错。
  • 如果需要排除多个字段,可以扩展比较逻辑,比如提取需要比较的字段列表统一处理:
    def __eq__(self, other):
        if not isinstance(other, SomeModel):
            return False
        # 定义需要比较的字段列表
        compare_fields = {"name", "content"}
        return all(getattr(self, field) == getattr(other, field) for field in compare_fields)
    

内容的提问来源于stack exchange,提问作者mousetail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 10:36:21