Python中将JSON列表映射为类实例属性的Pythonic实现方式
问题解答
首先明确:你原有代码里的循环遍历写法不是必须的,且原有代码存在一个常见的可变类属性陷阱:你当前把address: List[Address] = []定义为User的类属性,若实例化多个User对象,所有实例会共享同一个address列表,会出现数据互相污染的问题,建议优先在实例的__init__方法中初始化address属性。
以下是两种更Pythonic的实现方案:
方案1:原生Python无第三方依赖写法
直接用列表推导式替代循环append,代码更简洁,同时规避类属性共享问题:
from typing import List import json class Address(object): def __init__(self, street, number): self.street = street self.number = number def __str__(self): return "{0} {1}".format(self.street, self.number) class User(object): def __init__(self, name, address: List[dict]): self.name = name # 列表推导式一行完成列表内所有元素的类型转换 self.address: List[Address] = [Address(**adr) for adr in address] def __str__(self): return "{0} ,{1}".format(self.name, self.address)
方案2:类型标注自动序列化(复杂场景推荐)
如果项目允许引入第三方库,Pydantic是这类JSON转结构化类实例场景的最优解,你完全不需要手动写任何转换逻辑,只要定义好类型标注即可:
from typing import List from pydantic import BaseModel import json class Address(BaseModel): street: str number: int def __str__(self): return f"{self.street} {self.number}" class User(BaseModel): name: str address: List[Address] def __str__(self): return f"{self.name} ,{self.address}" if __name__ == '__main__': js = '''{ "name": "Cristian", "address": [{ "street": "Sesame", "number": 122 }, { "street": "Sesame", "number": 122 } ] }''' # 一步完成JSON字符串到类实例的转换,自动处理嵌套、列表结构 u = User.model_validate_json(js) print(u.name) print(u.address[0].number)
这种方式不仅不需要手动遍历转换列表,还自带参数合法性校验,字段不匹配时会抛出清晰的报错,适合业务逻辑比较复杂的场景。
内容的提问来源于stack exchange,提问作者Kinder9211
相关产品推荐
相关产品推荐

