Pydantic集合无法识别同名Child实例重复项问题求助
问题分析与解决方案
错误原因
你当前的问题出在Child类的哈希实现上:
- 你设置了
__hash__ = object.__hash__,这个哈希函数是基于对象内存地址生成的,两个name相同的Child实例是不同对象,因此哈希值完全不同。 - Python集合的去重逻辑是先比较哈希值,只有哈希值相同时才会调用
__eq__判断是否相等。虽然Pydantic的BaseModel默认会基于字段值实现__eq__(同名的Child实例会返回True),但由于哈希值不一致,集合不会触发__eq__的比较,直接将两个实例视为不同元素保留。
修正方案
要实现同名Child实例在集合中自动去重,需要让Child的哈希值和相等判断都基于name字段:
import pydantic class Child(pydantic.BaseModel): name: str # 基于name字段生成哈希值 def __hash__(self): return hash(self.name) # 显式定义相等判断逻辑,仅比较name def __eq__(self, other): if not isinstance(other, Child): return False return self.name == other.name def __str__(self): cls_name = self.__class__.__name__ return f"{cls_name}({self.name})" class Parent(pydantic.BaseModel): name: str children: set[Child] = set() def __str__(self): cls_name = self.__class__.__name__ return f"{cls_name}({self.name}, children={self.children})" data = dict( name="test", children=set([ Child(name="Child1"), Child(name="Child1"), ]) ) print(Parent(**data))
效果说明
运行修正后的代码,输出会变成:
Parent(test, children={Child(Child1)})
- 重写
__hash__后,同名Child实例的哈希值完全一致,集合会进一步调用__eq__判断,此时返回True,因此会自动去重。 - 显式重写
__eq__是为了明确去重规则仅依赖name,避免后续给Child添加其他字段时,默认的__eq__逻辑(比较所有字段)发生变化,影响去重效果。
内容的提问来源于stack exchange,提问作者DDStackoverflow
相关产品推荐
相关产品推荐

