如何在Pydantic BaseModel中基于其他字段设置默认值
在Pydantic BaseModel中让字段默认值依赖其他字段及外部字典的实现方法
你原来的代码无法运行的核心原因是:类定义阶段,letter只是字段的类型注解,并非实例化后的具体字段值,直接用MY_DICT[letter]会把str类型本身作为键去查字典,自然触发报错。
以下是两种可行的实现方案:
方案一:使用model_post_init方法
在模型实例初始化完成后,检查目标字段是否未赋值,若未赋值则根据第一个字段和外部字典生成默认值:
from pydantic import BaseModel, Field MY_DICT: dict[str, int] = { "a": 1, "b": 2, } class MyConfig(BaseModel): letter: str # 先将字段默认值设为None plus_one_by_default_or_any_int: int | None = Field(default=None) def model_post_init(self, __context) -> None: # 若用户未传入该字段值,自动计算默认值 if self.plus_one_by_default_or_any_int is None: self.plus_one_by_default_or_any_int = MY_DICT[self.letter] + 1
测试示例:
# 未传入第二个字段,自动生成默认值 config1 = MyConfig(letter="a") print(config1.plus_one_by_default_or_any_int) # 输出2 # 传入自定义值,优先使用用户指定的值 config2 = MyConfig(letter="b", plus_one_by_default_or_any_int=10) print(config2.plus_one_by_default_or_any_int) # 输出10
方案二:使用字段验证器field_validator
通过字段验证器,在字段校验阶段自动生成默认值,适合需要在验证环节处理的场景:
from pydantic import BaseModel, field_validator MY_DICT: dict[str, int] = { "a": 1, "b": 2, } class MyConfig(BaseModel): letter: str plus_one_by_default_or_any_int: int | None = None @field_validator('plus_one_by_default_or_any_int', mode='before') def set_default_value(cls, value, values): # 若字段未赋值,根据letter字段计算默认值 if value is None: return MY_DICT[values.data['letter']] + 1 # 已赋值则直接返回原数值 return value
测试效果与方案一完全一致。
内容的提问来源于stack exchange,提问作者michael
相关产品推荐
相关产品推荐

