FastAPI中json.dumps为新增User对象添加__pydantic_initialised__属性问题
问题描述
我正在使用FastAPI和JSON文件数据进行实验,通过app.put新增User对象后,使用json.dumps序列化时,新增对象会被添加一个"__pydantic_initialised__": true属性。
初始有两个User对象:
print(users) { '456rtz': User(vname='Niemand', nname='Nixda', email='niemand@nixda.none', role=3, mobile=0, street='', city='Zürich', zip=0, country='', id='456rtz'), '839f06fa-aa8c-4a77-9c5c-c036f913b18a': User(vname='Paulchen', nname='Panther', email='pp@00.org', role=3, mobile=0, street='', city='', zip=0, country='', id='839f06fa-aa8c-4a77-9c5c-c036f913b18a') }
执行users[user.id] = user新增用户后,users字典显示正常,但执行dstring = json.dumps([vars(item) for item in users.values()], indent=4)生成JSON字符串时,新用户的JSON中多了"__pydantic_initialised__": true属性,原有用户则没有。
由于我的User类没有该属性,从文件读取用户时程序崩溃。多次新增用户后,每个新用户都会被添加该属性。
请问为何会出现此情况?json.dumps如何区分新老对象?最重要的是如何阻止该行为?
问题原因与解决办法
原因分析
__pydantic_initialised__是Pydantic框架内部用于标记模型实例是否完成初始化的属性,属于框架维护的内部状态字段。- 原有用户对象可能是从JSON文件加载后通过非Pydantic标准流程创建的,没有触发这个内部标记;而通过FastAPI接口新增的User对象是由Pydantic严格按照自身初始化逻辑生成的,因此会附带这个属性。
vars()函数会读取对象的所有实例属性,包括Pydantic的内部隐藏属性,这才导致序列化时带出了__pydantic_initialised__。json.dumps本身不区分新老对象,只是被动序列化vars()返回的字典内容。
解决办法
不要使用vars()提取Pydantic模型字段,改用框架提供的官方方法过滤内部属性:
- Pydantic v2 使用
model_dump()方法,自动过滤内部字段,只返回模型定义的属性:
dstring = json.dumps([item.model_dump() for item in users.values()], indent=4)
- Pydantic v1 使用
dict()方法,效果与v2的model_dump()一致:
dstring = json.dumps([item.dict() for item in users.values()], indent=4)
如果需要定制序列化逻辑,还可以在方法中传入参数,比如exclude_unset=True只序列化已手动设置的字段,include/exclude指定需要包含或排除的特定字段。
内容的提问来源于stack exchange,提问作者McSvenster
相关产品推荐
相关产品推荐

