如何将Python类型转换为Pydantic风格的描述性字符串?
问题描述
我用Pydantic生成属性描述的JSON对象时,属性类型会输出"integer"这类标准JSON Schema格式的字符串。现在想以同样格式获取函数的返回类型,但用get_type_hints等方法只能得到<class 'int'>或"int",没法得到"integer"、"string"、"array"这类格式。查了Pydantic文档没找到明确方法,发现GenerateJsonSchema能做类型转换,但不知道怎么适配。想知道有没有通用方案,能不能借助Pydantic实现,或者是不是需要自定义映射。
示例代码
Pydantic属性类型示例
from pydantic import BaseModel, Field class MyModel(BaseModel): argument_1: int = Field(..., description="desc.") print(MyModel.model_json_schema()) # 输出: {'properties': {'argument_1': {'description': 'desc.', 'title': 'Argument 1', 'type': 'integer'}}, 'required': ['argument_1'], 'title': 'MyModel', 'type': 'object'}
函数返回类型获取示例
from typing import get_type_hints def get_return_type(obj): type_hints = get_type_hints(obj) return type_hints.get("return", "Unknown") def my_func() -> int: return 10 print(get_return_type(my_func)) print(my_func.__annotations__.get("return")) print(my_func.__annotations__.get("return").__name__) # 输出: <class 'int'> <class 'int'> int
解决方案
方案1:借助Pydantic的GenerateJsonSchema直接转换
Pydantic内置的JSON Schema生成器可以直接完成Python类型到JSON Schema标准类型的映射,无需自己维护规则:
from pydantic.json_schema import GenerateJsonSchema def get_json_schema_type(python_type): schema_generator = GenerateJsonSchema() # 生成对应类型的JSON Schema结构 schema = schema_generator.generate(python_type) # 处理可选类型、联合类型等复杂场景,优先取type字段 return schema.get('type', schema.get('anyOf', [{}])[0].get('type', 'unknown')) # 测试 def my_func() -> int: return 10 print(get_json_schema_type(my_func.__annotations__['return'])) # 输出: integer print(get_json_schema_type(str)) # 输出: string print(get_json_schema_type(list[int])) # 输出: array print(get_json_schema_type(int | None)) # 输出: integer(如需完整联合类型结构可直接返回schema)
这个方法完全复用Pydantic的类型处理逻辑,支持所有Pydantic兼容的复杂类型(泛型、联合类型、可选类型等)。
方案2:自定义基础类型映射表
如果只需要处理基础Python类型,自定义映射表是最轻量化的方案:
TYPE_MAPPING = { int: 'integer', str: 'string', bool: 'boolean', float: 'number', list: 'array', dict: 'object', type(None): 'null' } def get_json_schema_type(python_type): # 处理泛型类型(如list[int]),提取原始类型 if hasattr(python_type, '__origin__'): return TYPE_MAPPING.get(python_type.__origin__, 'unknown') # 处理基础类型 return TYPE_MAPPING.get(python_type, 'unknown') # 测试 print(get_json_schema_type(int)) # integer print(get_json_schema_type(list[str])) # array print(get_json_schema_type(bool)) # boolean
这种方式适合场景简单的需求,但需要自行扩展以支持复杂类型。
方案3:用Pydantic模型包装返回类型
通过临时创建一个仅包含返回类型的泛型Pydantic模型,利用模型的model_json_schema获取标准类型:
from pydantic import BaseModel from typing import TypeVar, Generic T = TypeVar('T') class ReturnWrapper(BaseModel, Generic[T]): __root__: T def get_json_schema_type(python_type): schema = ReturnWrapper[python_type].model_json_schema() return schema['properties']['__root__']['type'] # 测试 print(get_json_schema_type(int)) # integer print(get_json_schema_type(list[int])) # array print(get_json_schema_type(str)) # string
这个方法同样利用Pydantic的内置逻辑,代码简洁且支持复杂类型。
内容的提问来源于stack exchange,提问作者Trojo
相关产品推荐
相关产品推荐

