简体   繁体   English

Python 将 JSON 数组转换为 Python 对象的对应列表

[英]Python Convert JSON Array to Corresponding List of Python Objects

Couldn't find an already existing post that addressed how to do this: I have a JSON Array, like找不到解决如何执行此操作的现有帖子:我有一个 JSON 数组,例如

[{'completed': 0, 'content': 'do smtng', 'deadline': 'Mon, 22 Nov 2021 00:00:00 GMT', 'id': 4, 'user_id': 7}, ...], [{'完成':0,'内容':'做smtng','截止日期':'星期一,2021年11月22日00:00:00 GMT','id':4,'user_id':7},.. .],

and would like to convert it to a Python List of Task objects (from the Task class I created).想将其转换为任务对象的 Python 列表(来自我创建的任务 class)。

How would I go about doing this?我将如何 go 这样做?

What you are looking to do is deserialize a json object to a class, I'm sure there are better answers than this one but here goes.您要做的是将 json object 反序列化为 class,我敢肯定有比这个更好的答案,但这里有。

First Step: convert json array to python list第一步:将 json 数组转换为 python 列表

import json
# assuming it is a json object for now, you can loop through an do the same
json = {'completed': 0, 'content': 'do smtng', 'deadline': 'Mon, 22 Nov 2021 00:00:00 GMT', 'id': 4, 'user_id': 7}
job = json.loads(json)

Second Step: Converting our list to a class第二步:将我们的列表转换为 class

There's not really a consensus here on how to do this.关于如何做到这一点,这里并没有真正的共识。 You can try libraries like attrs if your json is already formatted with the exact naming of your class, or you can do something manual like this:如果您的 json 已经使用 class 的确切名称格式化,您可以尝试像 attrs 这样的库,或者您可以执行以下手动操作:

import json
from dataclasses import dataclass


@dataclass
class Task:
    completed: int
    content: str
    deadline: str
    id: int
    user_id: int
    
    @classmethod
    def from_dict(cls, dict):
        return cls(completed=dict["completed"], content=dict["content"],
                   deadline=dict["deadline"], id=dict["id"],
                   user_id=dict["user_id"])

    @classmethod
    def from_json(cls, json_str: str):
        return cls.from_dict(json.loads(json_str))

You can perform input validation here too if you want but trying to keep it basic如果您愿意,您也可以在此处执行输入验证,但尽量保持基本

If you're ok with using external libraries, the simplest solution would be to use the builtin dataclasses module in Python 3.7+ along with the dataclass-wizard library for (de)serialization purposes.如果您可以使用外部库,最简单的解决方案是使用dataclasses 3.7+ 中的内置数据类模块以及用于(反)序列化目的的数据类向导库。

Here's a simple enough example using data classes to model your data in this case.这是一个足够简单的示例,在这种情况下使用数据类 model 您的数据。 Note that I'm using a new feature, patterned date and time , to de-serialize a custom pattern string to a datetime object.请注意,我正在使用一个新功能, 模式化日期和时间,将自定义模式字符串反序列化为datetime时间 object。 If you want to keep the data as a string, you can annotate it just like deadline: str instead.如果您想将数据保留为字符串,您可以将其注释为deadline: str代替。 I was able to use the format codes from the docs on datetime.我能够使用日期时间文档中的格式代码。

import json
from dataclasses import dataclass

from dataclass_wizard import fromlist, asdict, DateTimePattern


@dataclass
class Task:
    completed: int
    content: str
    deadline: DateTimePattern['%a, %d %b %Y %H:%M:%S %Z']
    id: int
    user_id: int


list_of_dict = [
    {'completed': 0, 'content': 'do smtng', 'deadline': 'Mon, 22 Nov 2021 00:00:00 GMT', 'id': 4, 'user_id': 7},
]

# De-serialize JSON data into a list of Task instances
list_of_tasks = fromlist(Task, list_of_dict)
print(list_of_tasks)

# Serialize list of Task instances
json_string = json.dumps([asdict(task) for task in list_of_tasks])
print(json_string)

Output: Output:

[Task(completed=0, content='do smtng', deadline=datetime.datetime(2021, 11, 22, 0, 0), id=4, user_id=7)]
[{"completed": 0, "content": "do smtng", "deadline": "2021-11-22T00:00:00", "id": 4, "userId": 7}]

To make things a bit simpler, you can opt to subclass from the JSONWizard Mixin class.为了让事情变得更简单,您可以选择从JSONWizard Mixin class 子类化。 The main benefit here is a bunch of added helper class methods, like list_to_json which will serialize a list of dataclass instances to JSON, which seems like it could be useful in this case.这里的主要好处是添加了一堆辅助方法 class 方法,例如list_to_json它将数据类实例列表序列化为 JSON,这似乎在这种情况下很有用。 This example is similar to the one above;这个例子与上面的例子类似; note the output is the same in any case.注意 output 在任何情况下都是相同的。

from dataclasses import dataclass

from dataclass_wizard import JSONWizard, DateTimePattern


@dataclass
class Task(JSONWizard):
    completed: int
    content: str
    deadline: DateTimePattern['%a, %d %b %Y %H:%M:%S %Z']
    id: int
    user_id: int


list_of_dict = [
    {'completed': 0, 'content': 'do smtng', 'deadline': 'Mon, 22 Nov 2021 00:00:00 GMT', 'id': 4, 'user_id': 7},
]

# De-serialize JSON data into a list of Task instances
list_of_tasks = Task.from_list(list_of_dict)
print(list_of_tasks)

# Serialize list of Task instances
json_string = Task.list_to_json(list_of_tasks)
print(json_string)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM