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

为Pydantic添加quantiphy.Quantity数据类型的序列化反序列化支持

解决Pydantic处理quantiphy.Quantity类型的序列化/反序列化问题

问题原因

Pydantic v2无法自动为quantiphy.Quantity生成核心Schema,且旧版的json_encoders仅负责序列化阶段,无法解决Schema生成失败的报错,必须明确指定该类型的双向转换规则(字符串转Quantity、Quantity转字符串)。

解决方案:使用Annotated+Validator/Serializer(Pydantic v2推荐方式)

通过Annotated结合BeforeValidator(反序列化)和PlainSerializer(序列化),为Quantity类型定义完整的转换逻辑,让Pydantic能正确生成Schema并处理双向转换。

完整代码示例

from pydantic import BaseModel, BeforeValidator, PlainSerializer, Annotated
from quantiphy import Quantity

# 定义反序列化函数:字符串转Quantity
def str_to_quantity(value):
    if isinstance(value, str):
        return Quantity(value)
    return value

# 定义序列化函数:Quantity转字符串
def quantity_to_str(quantity):
    return str(quantity)

# 封装带转换规则的Annotated类型
QuantityStr = Annotated[
    Quantity,
    BeforeValidator(str_to_quantity),
    PlainSerializer(quantity_to_str, return_type=str)
]

class SpecLimit(BaseModel):
    label: str
    minimum: QuantityStr | None = None
    maximum: QuantityStr | None = None
    typical: QuantityStr | None = None
    is_informative: bool = False

# 测试序列化
spec = SpecLimit(label="Voltage", minimum=Quantity("5V"), maximum=Quantity("10V"))
print(spec.model_dump_json(indent=2))
# 输出:
# {
#   "label": "Voltage",
#   "minimum": "5 V",
#   "maximum": "10 V",
#   "typical": null,
#   "is_informative": false
# }

# 测试反序列化
json_data = '''{
    "label": "Current",
    "minimum": "2A",
    "typical": "3.5A"
}'''
spec2 = SpecLimit.model_validate_json(json_data)
print(f"minimum值类型:{type(spec2.minimum)},值:{spec2.minimum}")
# 输出:minimum值类型:<class 'quantiphy.quantiphy.Quantity'>,值:2 A

替代方案:使用TypeAdapter

如果需要在多个模型中复用Quantity的转换规则,可以定义TypeAdapter,然后通过Field指定:

from pydantic import BaseModel, TypeAdapter, Field
from quantiphy import Quantity

# 定义转换函数(同前)
def str_to_quantity(value):
    if isinstance(value, str):
        return Quantity(value)
    return value

def quantity_to_str(quantity):
    return str(quantity)

# 创建TypeAdapter
quantity_adapter = TypeAdapter(
    Annotated[Quantity, BeforeValidator(str_to_quantity), PlainSerializer(quantity_to_str)]
)

class SpecLimit(BaseModel):
    label: str
    minimum: Quantity | None = Field(default=None, adapter=quantity_adapter)
    maximum: Quantity | None = Field(default=None, adapter=quantity_adapter)
    typical: Quantity | None = Field(default=None, adapter=quantity_adapter)
    is_informative: bool = False

为什么旧方法无效

json_encoders在Pydantic v2中已被废弃,且仅能处理序列化时的格式转换,无法帮助Pydantic生成Quantity类型的核心Schema,因此会出现PydanticSchemaGenerationError报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:12:40