📜  在Python中序列化和反序列化复杂的 JSON

📅  最后修改于: 2022-05-13 01:54:47.091000             🧑  作者: Mango

在Python中序列化和反序列化复杂的 JSON

JSON 代表 JavaScript 对象表示法。它是一种以字符串格式对数据进行编码的格式。 JSON 是独立于语言的,因此,它用于在文件中存储或传输数据。从 JSON 对象字符串转换数据称为序列化,其相反的字符串JSON 对象称为反序列化。 JSON 对象使用花括号{} 定义,由键值对组成。需要注意的是,JSON 对象键是一个字符串,它的值可以是任何基本类型(例如 int、 字符串、null)或复杂数据类型(例如数组)。

JSON 对象示例:

{
 "id":101,
 "company" : "GeeksForGeeks"
}

复杂 JSON 对象是那些在另一个对象中包含嵌套对象的对象。复杂 JSON 对象的示例。

{
 "id":101,
 "company" : "GeeksForGeeks",
 "Topics" : { "Data Structure",
              "Algorithm",
              "Gate Topics" }
}

序列化和反序列化

Python和 JSON 模块与字典配合得非常好。对于 JSON 对象的序列化和反序列化,可以使用Python “__dict__”。任何Python对象上都有 __dict__ ,它是用于存储对象(可写)属性的字典。我们可以用它来处理 JSON,而且效果很好。
代码:

Python3
import json
  
  
class GFG_User(object):
    def __init__(self, first_name: str, last_name: str):
        self.first_name = first_name
        self.last_name = last_name
          
user = GFG_User(first_name="Jake", last_name="Doyle")
json_data = json.dumps(user.__dict__)
print(json_data)
print(GFG_User(**json.loads(json_data)))


Python3
from typing import List
import json
  
  
class Student(object):
    def __init__(self, first_name: str, last_name: str):
        self.first_name = first_name
        self.last_name = last_name
  
  
class Team(object):
    def __init__(self, students: List[Student]):
        self.students = students
  
  
student1 = Student(first_name="Geeky", last_name="Guy")
student2 = Student(first_name="GFG", last_name="Rocks")
team = Team(students=[student1, student2])
json_data = json.dumps(team.__dict__, indent=4)
print(json_data)


Python3
from typing import List
import json
  
  
class Student(object):
    def __init__(self, first_name: str, last_name: str):
        self.first_name = first_name
        self.last_name = last_name
  
  
class Team(object):
    def __init__(self, students: List[Student]):
        self.students = students
  
  
student1 = Student(first_name="Geeky", last_name="Guy")
student2 = Student(first_name="GFG", last_name="Rocks")
team = Team(students=[student1, student2])
  
# Serialization
json_data = json.dumps(team, default=lambda o: o.__dict__, indent=4)
print(json_data)
  
# Deserialization
decoded_team = Team(**json.loads(json_data))
print(decoded_team)


输出:

{"first_name": "Jake", "last_name": "Doyle"} 
__main__.GFG_User object at 0x105ca7278

注意: GFG_User(**json.load(json_data) 行中的双星号 ** 可能看起来令人困惑。但它所做的只是扩展字典。

复杂对象

现在在处理复杂的 JSON 对象时事情变得很棘手,因为我们的技巧“__dict__”不再起作用了。
代码:

Python3

from typing import List
import json
  
  
class Student(object):
    def __init__(self, first_name: str, last_name: str):
        self.first_name = first_name
        self.last_name = last_name
  
  
class Team(object):
    def __init__(self, students: List[Student]):
        self.students = students
  
  
student1 = Student(first_name="Geeky", last_name="Guy")
student2 = Student(first_name="GFG", last_name="Rocks")
team = Team(students=[student1, student2])
json_data = json.dumps(team.__dict__, indent=4)
print(json_data)

输出:

TypeError: Object of type Student is not JSON serializable

但是,如果您查看转储函数的文档,您会看到我们可以使用默认设置。只需替换此行:

json_data = json.dumps(team.__dict__, indent=4)

通过这一行:

json_data = json.dumps(team.__dict__, lambda o: o.__dict__, indent=4)

现在一切正常。现在,让我们看看反序列化:
代码:

Python3

from typing import List
import json
  
  
class Student(object):
    def __init__(self, first_name: str, last_name: str):
        self.first_name = first_name
        self.last_name = last_name
  
  
class Team(object):
    def __init__(self, students: List[Student]):
        self.students = students
  
  
student1 = Student(first_name="Geeky", last_name="Guy")
student2 = Student(first_name="GFG", last_name="Rocks")
team = Team(students=[student1, student2])
  
# Serialization
json_data = json.dumps(team, default=lambda o: o.__dict__, indent=4)
print(json_data)
  
# Deserialization
decoded_team = Team(**json.loads(json_data))
print(decoded_team)

输出:

{
    "students": [
        {
            "first_name": "Geeky",
            "last_name": "Guy"
        },
        {
            "first_name": "GFG",
            "last_name": "Rocks"
        }
    ]
}
__main__.Team object at 0x105cd41d0