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

如何用Pydantic BaseModel管理场景可选输入参数?

如何用Pydantic BaseModel实现参数依赖校验规则?

我用pydantic.BaseModel定义了一个输入类Product,其中部分参数存在场景化的必填规则:

from pydantic import BaseModel

class Product(BaseModel):
    name: str
    sale_price: float | None = None
    cost_manufacture: float | None = None
    cost_transport: float | None = None
    earning_ratio: float | None = None

规则如下:

  • 若提供sale_price,则cost_manufacture、cost_transport和earning_ratio必须保持默认值None,无需提供
  • 若未提供sale_price,则必须同时提供cost_manufacture、cost_transport和earning_ratio

之前仅通过Field添加描述的方式不够优雅,会增加用户阅读成本,需要一种能自动校验该依赖规则的实现方式。


解决方案:使用Pydantic的模型验证器

针对Pydantic v2版本

使用model_validator(设置mode='after')实现跨字段的依赖校验:

from pydantic import BaseModel, model_validator, ValidationError

class Product(BaseModel):
    name: str
    sale_price: float | None = None
    cost_manufacture: float | None = None
    cost_transport: float | None = None
    earning_ratio: float | None = None

    @model_validator(mode='after')
    def check_parameter_dependency(self) -> 'Product':
        # 提供sale_price时,检查成本相关参数是否全为None
        if self.sale_price is not None:
            if any([self.cost_manufacture, self.cost_transport, self.earning_ratio]):
                raise ValueError("当提供sale_price时,cost_manufacture、cost_transport和earning_ratio必须为None")
        # 未提供sale_price时,检查成本相关参数是否全部提供
        else:
            if not all([self.cost_manufacture, self.cost_transport, self.earning_ratio]):
                raise ValueError("当未提供sale_price时,必须同时提供cost_manufacture、cost_transport和earning_ratio")
        return self

# 测试示例
if __name__ == "__main__":
    # 合法:仅提供sale_price
    try:
        product1 = Product(name="Test", sale_price=100.0)
        print(product1)
    except ValidationError as e:
        print(e)

    # 合法:仅提供成本相关参数
    try:
        product2 = Product(name="Test", cost_manufacture=50.0, cost_transport=10.0, earning_ratio=0.2)
        print(product2)
    except ValidationError as e:
        print(e)

    # 非法:同时提供sale_price和成本参数
    try:
        product3 = Product(name="Test", sale_price=100.0, cost_manufacture=50.0)
        print(product3)
    except ValidationError as e:
        print(e)

    # 非法:未提供sale_price但缺少成本参数
    try:
        product4 = Product(name="Test", cost_manufacture=50.0, cost_transport=10.0)
        print(product4)
    except ValidationError as e:
        print(e)

针对Pydantic v1版本

若仍使用Pydantic v1,可使用root_validator(设置pre=False):

from pydantic import BaseModel, root_validator, ValidationError

class Product(BaseModel):
    name: str
    sale_price: float | None = None
    cost_manufacture: float | None = None
    cost_transport: float | None = None
    earning_ratio: float | None = None

    @root_validator(pre=False)
    def check_parameter_dependency(cls, values):
        sale_price = values.get("sale_price")
        cost_manufacture = values.get("cost_manufacture")
        cost_transport = values.get("cost_transport")
        earning_ratio = values.get("earning_ratio")

        if sale_price is not None:
            if any([cost_manufacture, cost_transport, earning_ratio]):
                raise ValueError("当提供sale_price时,cost_manufacture、cost_transport和earning_ratio必须为None")
        else:
            if not all([cost_manufacture, cost_transport, earning_ratio]):
                raise ValueError("当未提供sale_price时,必须同时提供cost_manufacture、cost_transport和earning_ratio")
        return values

# 测试示例同v2版本

优势说明

  • 自动执行校验,不符合规则时直接抛出ValidationError,无需用户手动判断
  • 校验逻辑集中,代码结构清晰,维护成本低
  • 完全兼容Pydantic原生校验机制,适配现有输入处理流程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 07:37:37