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

基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 05:12:42