基于Pydantic实现延迟获取字段的断言验证及兼容问题
带可选/可获取字段的Pydantic API字段断言实现问题
我正在开发一个返回Pydantic对象的API,其中包含可选/“可获取”字段——这些字段是否被获取完全取决于传入的API参数。我希望在访问这类可选字段时,能通过断言确认该字段已经被实际获取。
可行但繁琐的方案:Getter/Setter
为每个字段手动添加getter和setter可以实现需求,但这种方式过于繁琐,当对象中有大量这类字段时工作量巨大,而且后续扩展序列化等功能也会受限:
_field_a: int | NotFetched = NOT_FETCHED @property def field_a(self) -> int: return assert_fetched(self._field_a) @field_a.setter def field_a(self, value): self._field_a = value
更优但兼容有问题的方案:描述符类
我尝试用描述符类来简化实现,代码如下:
from typing import Generic, T, Any class FetchableField(Generic[T]): def __set_name__(self, owner: type, name: str) -> None: self.public_name = name self.private_name = f"_{name}" def __get__(self, instance: Any, owner: type | None = None) -> T: if instance is None: return self # pyright: ignore[reportReturnType] return assert_fetched( getattr(instance, self.private_name, NOT_FETCHED), self.public_name, ) def __set__(self, instance: Any, value: T) -> None: setattr(instance, self.private_name, value) # 使用示例 class Object: _field_a: int | NotFetched = NOT_FETCHED # 可选字段 field_a: int = FetchableField()
但实际使用中发现这个方案和Pydantic不兼容,出现了以下问题:
obj = Object() obj.a # 返回的是<FetchableField object>,完全没有触发FetchableField中的getter方法
内容的提问来源于stack exchange,提问作者XXXHHHH
相关产品推荐
相关产品推荐

