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

如何用字典实例化含自定义嵌套类型的Python对象?

解决嵌套类实例化与类型校验的问题

咱们先拆解你遇到的两个核心问题,再一步步给出解决方案:

第一个错误的根源

你原来的ensure_type函数只会校验已有值的类型,但你的education字段是字典列表([{'school_name':'foo'}, ...]),这些字典还没有被实例化成Education对象,直接让它校验是否是Education类型,肯定会触发类型错误——因为字典本来就不是Education实例呀!

第二个错误的原因

你改成self.education = Education(kwargs.get('education'))后,相当于把整个列表[{'school_name':'foo'}, ...]传给了Education的__init__,但Education的构造函数只接受关键字参数(**kwargs),不接受位置参数,所以才会报“参数数量不匹配”的错误。

解决方案:改造类型校验函数,支持自动实例化嵌套类

我们需要让ensure_type不仅能校验类型,还能在遇到字典(或字典列表)且目标类型是类时,自动把字典转换成对应的类实例。同时还要保留必填字段的校验逻辑。

1. 改造ensure_type函数

def ensure_type(value, types):
    # 处理列表:逐个元素校验/转换
    if isinstance(value, list):
        return [ensure_type(element, types) for element in value]
    # 处理字典:如果目标是类,就用字典实例化;否则递归校验字典值
    elif isinstance(value, dict):
        if isinstance(types, type):
            return types(**value)
        else:
            for k, v in value.items():
                value[k] = ensure_type(v, types)
            return value
    # 普通类型直接校验
    elif isinstance(value, types):
        return value
    else:
        raise TypeError(f'Value {value} is {type(value)}, but should be {types}!')

2. 调整类的构造函数,增加必填字段校验

我们在__init__里先检查必填字段是否存在,再用改造后的ensure_type做类型校验和实例化:

class Education:
    def __init__(self, **kwargs):
        # 校验必填字段
        if 'school_name' not in kwargs:
            raise ValueError('"school_name" is a required field for Education')
        self.school_name = ensure_type(kwargs['school_name'], str)

class Employee:
    def __init__(self, **kwargs):
        # 校验必填字段
        if 'fname' not in kwargs:
            raise ValueError('"fname" is a required field for Employee')
        if 'education' not in kwargs:
            raise ValueError('"education" is a required field for Employee')
        
        self.fname = ensure_type(kwargs['fname'], str)
        # 这里传入Education作为类型,函数会自动把字典列表转成Education实例列表
        self.education = ensure_type(kwargs['education'], Education)

3. 测试代码

运行你的测试代码:

if __name__ == "__main__":
    emp_dict = {'fname': 'Bob', 'education': [{'school_name':'foo'}, {'school_name':'bar'}]}
    employee1 = Employee(**emp_dict)
    
    # 验证结果
    print(employee1.fname)  # 输出: Bob
    print([edu.school_name for edu in employee1.education])  # 输出: ['foo', 'bar']

这样就能正确实例化嵌套类,同时保证必填字段不缺失,类型也符合要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:18:11