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

如何高效解析Pydantic v2自引用类的model_json_schema的properties?

问题解答

你的思路方向是对的,针对Pydantic v2中自引用类的JSON Schema引用问题,这个resolve_ref函数是直接且高效的实现方式,同时可以做一些小优化让它更健壮:

核心逻辑的合理性

Pydantic处理自引用(或循环引用)模型时,会自动把重复的Schema定义提取到$defs中,并用$ref指向它,这是符合JSON Schema规范的行为。你的函数通过解析$ref路径直接从$defs中获取目标Schema,逻辑完全贴合Pydantic的生成规则,没有多余开销,属于直接的解决方案。

可优化点

  1. 兼容非自引用场景:先检查当前Schema是否直接包含properties,不用走引用解析流程
  2. 简化字符串操作:用removeprefix替代切片,代码更易读
  3. 增强空值容错:提前判断$ref是否存在,避免字符串操作报错

优化后的示例函数:

def get_model_properties(schema: dict) -> dict | None:
    """从Pydantic生成的JSON Schema中获取properties字典,自动处理自引用"""
    # 优先检查当前schema是否直接包含properties
    if "properties" in schema:
        return schema["properties"]
    # 处理$ref引用
    ref_value = schema.get("$ref")
    if not ref_value or not ref_value.startswith("#/$defs/"):
        return None
    def_name = ref_value.removeprefix("#/$defs/")
    return schema.get("$defs", {}).get(def_name, {}).get("properties")

验证示例

用你的测试代码验证优化后的函数:

import pydantic
from typing import Optional
from pydantic import BaseModel

class Node(BaseModel):
    myprop: str
    children: Optional["FailingNode"] = None

class FailingNode(BaseModel):
    myprop: str
    children: Optional["FailingNode"] = None

def get_model_properties(schema: dict) -> dict | None:
    if "properties" in schema:
        return schema["properties"]
    ref_value = schema.get("$ref")
    if not ref_value or not ref_value.startswith("#/$defs/"):
        return None
    def_name = ref_value.removeprefix("#/$defs/")
    return schema.get("$defs", {}).get(def_name, {}).get("properties")

if __name__ == "__main__":
    # 非自引用模型
    good_schema = Node(myprop="good").model_json_schema()
    print(get_model_properties(good_schema).keys())  # 输出: dict_keys(['myprop', 'children'])
    
    # 自引用模型
    bad_schema = FailingNode(myprop="bad").model_json_schema()
    print(get_model_properties(bad_schema).keys())  # 输出: dict_keys(['myprop', 'children'])

结论

你最初的resolve_ref函数已经是高效且直接的实现,优化后的版本进一步适配了非自引用场景,逻辑更完整。在Pydantic v2的生态下,这种直接解析$defs的方式是处理自引用Schema最直接的手段,没有额外性能损耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:02:48