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

Python 3.10搭配FastAPI时字典字段顺序错乱问题排查

问题原因
  • 你看到的pprint输出顺序错乱是假象:Python 3.8+版本的pprint.pprint()默认参数sort_dicts=True,会自动对字典key按字母序排序后打印,和字典实际存储的插入顺序完全无关。
  • Python 3.10的原生字典确实默认保留插入顺序,你代码里动态生成的字典在内存里的顺序是对的,顺序错乱发生在序列化输出JSON的环节:FastAPI/Starlette默认的JSON序列化逻辑如果检测到环境里有高阶JSON库(比如orjson),或者默认配置开启了key排序,就会打乱你原有字典的字段顺序。
  • 之前尝试用OrderedDict无效的原因有两个:一是你只替换了card层级的字典为OrderedDict,外层返回结构、tokens数组内的字典依然是普通dict,没有全量替换;二是即使全量用OrderedDict,只要序列化环节开启了key排序,最终输出依然会乱序。
解决方案

1. 先排除pprint的干扰

把你代码里的pprint调用改成如下形式,就能看到字典真实的存储顺序:

pprint(all_cards, sort_dicts=False)

如果此时打印顺序和你定义的一致,就可以确认问题只出在接口返回的序列化阶段。

2. 自定义保序的JSON响应(快速修复)

自定义一个关闭key排序的JSON响应类,挂载到对应接口上即可,不需要修改原有数据生成逻辑:

from fastapi import FastAPI
from fastapi.responses import JSONResponse
import json

# 自定义保序JSON响应
class SortedFreeJSONResponse(JSONResponse):
    def render(self, content) -> bytes:
        return json.dumps(
            content,
            ensure_ascii=False,
            sort_keys=False, # 核心:禁止自动排序key
            separators=(",", ":")
        ).encode("utf-8")

app = FastAPI()

# 在接口上指定使用自定义响应类
@app.get("/", response_class=SortedFreeJSONResponse)
async def root():
    # 原有数据获取逻辑
    all_cards = create_contract_cards(data)
    return all_cards

这个方案下你不需要修改create_contract_cards里的字典写法,原生dict的插入顺序会被完整保留到返回的JSON中。

3. Pydantic模型强约束顺序(生产环境推荐)

如果要长期保证字段顺序不被依赖版本、配置变动影响,最好的方式是用Pydantic按你需要的顺序定义响应模型,FastAPI会严格按照模型声明的字段顺序序列化:

from pydantic import BaseModel
from typing import Literal

# 严格按需要的输出顺序定义字段
class TokenInfo(BaseModel):
    label: str
    dataType: Literal["STRING", "STATUS"]
    value: str
    name: str

class SectionCard(BaseModel):
    id: str
    title: str
    linkUrl: str
    tokens: list[TokenInfo]

class ApiResponse(BaseModel):
    responseVersion: Literal["v3"]
    totalCount: int
    sections: list[SectionCard]

然后在接口装饰器上指定响应模型即可:

@app.get("/", response_model=ApiResponse, response_class=SortedFreeJSONResponse)
async def root():
    all_cards = create_contract_cards(data)
    return all_cards

这种方式同时会自动做字段类型校验,避免返回结构不符合对接要求。

补充说明:JSON官方规范本身没有强制要求字段顺序,但如果对接方有明确的顺序要求,上述两种方案都可以稳定满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:39:59