将Pydantic验证器浓缩为Python类注解的实现需求
如何将Pydantic验证器简化为单行字段定义形式
如果你想把Pydantic中用@validator装饰器实现的字段计算逻辑,改成直接在字段定义时指定的单行形式,可以通过自定义描述符来实现,既能保留Pydantic的类型验证能力,又能让代码更简洁。
实现方案
我们可以创建一个描述符类,用来存储字段的原始输入值,并在访问字段时自动执行依赖其他字段的计算逻辑:
from pydantic import BaseModel class CalculatedField: def __init__(self, compute_func): self.compute_func = compute_func self.field_name = None self.input_attr = None def __set_name__(self, owner, name): self.field_name = name self.input_attr = f"_{name}_raw" # 存储原始输入的属性名 def __get__(self, instance, owner): if instance is None: return self # 调用计算函数,传入实例以访问其他字段 return self.compute_func(instance) def __set__(self, instance, value): # 保存原始输入值 setattr(instance, self.input_attr, value) # 定义具体的计算函数 def compute_b(instance): return instance.a + getattr(instance, "_b_raw") def compute_c(instance): return instance.a + instance.b + getattr(instance, "_c_raw") # 最终的类定义 class MyClass(BaseModel): a: str b: str = CalculatedField(compute_b) c: str = CalculatedField(compute_c)
使用示例
创建实例时传入原始值,访问字段时会自动计算:
obj = MyClass(a="foo", b="bar", c="baz") print(obj.b) # foobar print(obj.c) # foobarbaz
说明
CalculatedField作为描述符,会自动为每个字段创建一个存储原始输入的隐藏属性(比如_b_raw)- 计算函数
compute_b和compute_c接收实例作为参数,可以直接访问其他字段的值 - 字段定义时直接赋值为
CalculatedField(计算函数),完全符合你想要的单行形式 - 保留了Pydantic的类型验证能力:传入的原始值会被自动验证是否符合
str类型要求
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

