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

如何获取Python类所有变量(含未赋值项)实现动态字段校验

解决方案

Python 3.6+ 原生支持通过类的__annotations__属性获取所有通过类型注解声明的类字段,无论这个字段有没有赋值默认值,刚好匹配需求,不需要依赖任何第三方库。

核心逻辑

你定义的类中,所有形如height: int、is_alive: bool = True的字段,都会被记录到类的__annotations__字典中,键为字段名,值为字段标注的类型。校验时只需要区分三类字段即可:

  • 所有声明过的字段:从__annotations__中获取
  • 有默认值的字段:存在于类本身的__dict__属性中
  • 已经通过链式方法手动赋值的字段:存在于实例的__dict__属性中
    只要某个声明过的字段既没有默认值,也没有被手动赋值,就属于校验不通过的缺失字段。

完整实现代码

class Query:
    height: int
    weight: int
    age: int
    name: str
    is_alive: bool = True

    def of_height(self, height):
        self.height = height
        return self

    def with_name(self, name):
        self.name = name
        return self
    
    def of_weight(self, weight):
        self.weight = weight
        return self
    
    def of_age(self, age):
        self.age = age
        return self

    def validate(self):
        # 获取当前类所有声明的注解字段
        declared_fields = self.__class__.__annotations__.keys()
        missing = []
        for field in declared_fields:
            # 字段既没有手动赋值,也没有默认值则标记为缺失
            if field not in self.__dict__ and field not in self.__class__.__dict__:
                missing.append(field)
        if missing:
            raise ValueError(f"缺失必填查询字段: {', '.join(missing)}")
        # 校验通过后可在这里编写后续API请求构造逻辑
        return True

效果测试

# 场景1:仅赋值height、name,缺失weight、age
q = Query()
q.of_height(175).with_name("Alice")
try:
    q.validate()
except ValueError as e:
    print(e)  # 输出:缺失必填查询字段: weight, age

# 场景2:所有必填字段赋值完成
q2 = Query()
q2.of_height(175).with_name("Alice").of_weight(65).of_age(25)
q2.validate()  # 校验正常通过
print(q2.is_alive)  # 输出:True,正常读取类默认值

扩展适配场景

  • 支持类继承:如果你的Query类会被其他类继承,需要把父类声明的字段也纳入校验,只需要替换validate中获取声明字段的逻辑,顺着类的继承链(__mro__)合并所有父类的注解即可:
    def get_all_declared_fields(cls):
        fields = {}
        # 反向遍历继承链,保证子类字段覆盖父类同名字段
        for klass in reversed(cls.__mro__):
            fields.update(getattr(klass, "__annotations__", {}))
        return fields.keys()
    
    调用时传入self.__class__就能拿到所有继承来的声明字段。
  • 适配无注解的类属性:如果后续有直接赋值、没写类型注解的类属性需要被校验,只需要在收集声明字段时,把类__dict__中不是方法、不是双下划线特殊属性的键合并进去即可。

这个方案完全动态,后续新增查询字段时,只要按照现有风格写类型注解:如果是必填字段就只写类型不赋值,如果是可选字段就直接给默认值,validate方法不需要做任何修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 22:31:01