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

使用Pydantic解析JSON数据时遭遇float类型验证错误求助

解决Pydantic解析带千分位的价格字符串为float的问题

问题重现

Python代码

import json
import pydantic
from typing import Optional, List


class Car(pydantic.BaseModel):
    manufacturer: str
    model: str
    date_of_manufacture: str
    date_of_sale: str
    number_plate: str
    price: float
    type_of_fuel: Optional[str]
    location_of_sale: Optional[str]


def load_data() -> None:
    with open("./data.json") as file:
        data = json.load(file)
        cars: List[Car] = [Car(**item) for item in data]
        print(cars[0])


if __name__ == "__main__":
    load_data()

JSON数据

[
    {
        "manufacturer": "BMW",
        "model": "i8",
        "date_of_manufacture": "14/06/2021",
        "date_of_sale": "19/11/2022",
        "number_plate": "ND21WHP",
        "price": "100,000",
        "type_of_fuel": "electric",
        "location_of_sale": "Leicester, England"
    },
    {
        "manufacturer": "Audi",
        "model": "TT RS",
        "date_of_manufacture": "22/02/2019",
        "date_of_sale": "12/08/2021",
        "number_plate": "LR69FOW",
        "price": "67,000",
        "type_of_fuel": "petrol",
        "location_of_sale": "Manchester, England"
    }
]

错误信息

File "pydantic\main.py", line 342, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for Car
price value is not a valid float (type=type_error.float)

错误原因

JSON中的price字段是带千分位逗号的字符串(如"100,000"),Pydantic默认的float类型解析无法识别这种格式——逗号不是浮点数的合法组成字符,即使在末尾添加.00,只要逗号存在就会解析失败。

解决方法

方法1:使用Pydantic的@validator装饰器处理

在Car类中添加验证器,自动清理价格字符串中的逗号并转换为float:

import json
from pydantic import BaseModel, validator
from typing import Optional, List


class Car(BaseModel):
    manufacturer: str
    model: str
    date_of_manufacture: str
    date_of_sale: str
    number_plate: str
    price: float
    type_of_fuel: Optional[str]
    location_of_sale: Optional[str]

    @validator('price', pre=True)
    def parse_price(cls, value):
        # 如果是字符串,去掉逗号后转float
        if isinstance(value, str):
            return float(value.replace(',', ''))
        return value


def load_data() -> None:
    with open("./data.json") as file:
        data = json.load(file)
        cars: List[Car] = [Car(**item) for item in data]
        print(cars[0])


if __name__ == "__main__":
    load_data()

pre=True表示这个验证器在Pydantic默认类型检查之前执行,先把处理后的数值传给字段解析。

方法2:解析JSON后预处理数据

在加载JSON后,先遍历每个条目处理price字段,再传给Pydantic:

import json
from pydantic import BaseModel
from typing import Optional, List


class Car(BaseModel):
    manufacturer: str
    model: str
    date_of_manufacture: str
    date_of_sale: str
    number_plate: str
    price: float
    type_of_fuel: Optional[str]
    location_of_sale: Optional[str]


def load_data() -> None:
    with open("./data.json") as file:
        data = json.load(file)
        # 预处理每个条目,清理price字段
        for item in data:
            if isinstance(item['price'], str):
                item['price'] = float(item['price'].replace(',', ''))
        cars: List[Car] = [Car(**item) for item in data]
        print(cars[0])


if __name__ == "__main__":
    load_data()

方法3:自定义Pydantic字段类型

如果需要在多个模型中复用这种价格解析逻辑,可以自定义字段类型:

import json
from pydantic import BaseModel
from typing import Optional, List, Any
from pydantic.fields import ModelField


class Price(float):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v: Any, field: ModelField, config):
        if isinstance(v, str):
            return cls(v.replace(',', ''))
        return cls(v)


class Car(BaseModel):
    manufacturer: str
    model: str
    date_of_manufacture: str
    date_of_sale: str
    number_plate: str
    price: Price
    type_of_fuel: Optional[str]
    location_of_sale: Optional[str]


def load_data() -> None:
    with open("./data.json") as file:
        data = json.load(file)
        cars: List[Car] = [Car(**item) for item in data]
        print(cars[0])


if __name__ == "__main__":
    load_data()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:31:14