5种方法Python将JSON转换为自定义Python对象/类_python json转对象

Python使用json.load() 和 json.loads() 方法从文件或字符串加载 JSON 数据时,它会返回一个dict。如果我们将 JSON 数据直接加载到我们的自定义类型中,我们可以更轻松地操作和使用它。有多种方法可以实现这一点,你可以选择你认为对你的问题更有用的方式。让我们看看如何将 JSON 字符串反序列化为自定义 Python 对象。

推荐的方式

https://blog.csdn.net/HYZX_9987/article/details/125225121

通过把json.loads解析出来的dict赋值给类对象的.__dict__属性完成对象属性填充

  1. def ParseJsonToObj(jsonStr, objClass):
  2. parseData = json.loads(jsonStr.strip('\t\r\n'))
  3. result = objClass()
  4. result.__dict__ = parseData
  5. return result
  6. # 使用示例
  7. class Student(object):
  8. def __init__(self):
  9. self.name= ""
  10. self.age= 0
  11. self.causes= []
  12. jsonStr = '{"name": "ww", "age": 99, "causes": ["A","B"]}'
  13. stu = ParseJsonToObj(jsonStr, Student)
  14. print("result={}, type={}".format(stu, type(stu)))
  15. print("name={}, age={}, causes={}".format(stu.name,stu.age,stu.causes))

http://www.webkaka.com/tutorial/zhanzhang/2021/1228117/

1.使用namedtuple和object_hook将JSON转换为自定义Python对象

我们可以使用json.loads()和json.load()方法中的object_hook参数,这是一个可选函数,将使用任何对象文字解码的结果(字典dict)调用,所以当我们执行json.loads()时,object_hook的返回值将用字典dict代替。使用此功能,我们可以实现自定义解码器

正如我们所知json.load()json.loads()方法将 JSON 转换为dict对象,因此我们需要创建一个自定义函数,我们可以在其中转换dict为自定义 Python 类型。并将这个新创建的函数传递给json.loads方法的object_hook参数。所以我们可以在解码JSON时获得自定义类型。

namedtuple是集合模块下的类。与字典类型对象一样,它包含键并映射到某些值。在这种情况下,我们可以使用键和索引访问元素。

让我们先看一个简单的例子,然后我们才能进入实际的例子。在此示例中,我们将学生JSON数据转换为自定义学生类类型。

 
    1. import json
    2. from collections import namedtuple
    3. from json import JSONEncoder
    4. def customStudentDecoder(studentDict):
    5.     return namedtuple('X', studentDict.keys())(*studentDict.values())
    6. #Assume you received this JSON response
    7. studentJsonData = '{"rollNumber": 1, "name": "Emma"}'
    8. # Parse JSON into an object with attributes corresponding to dict keys.
    9. student = json.loads(studentJsonData, object_hook=customStudentDecoder)
    10. print("After Converting JSON Data into Custom Python Object")
    11. print(student.rollNumber, student.name)
    '
    运行

输出:

    1. After Converting JSON Data into Custom Python Object
    2. 1 Emma

如你所见,我们将 JSON 字符串格式的 JSON 数据转换为自定义 Python 对象 Student。现在,我们可以使用 dot(.) 运算符访问其成员。

现在,让我们看看使用复杂 Python 对象的实时场景。我们需要将自定义 Python 对象转换为 JSON。此外,我们想从 JSON 构造一个自定义的 Python 对象。

在这个例子中,我们使用了两个类StudentMarksMarks类是Student类的成员。

  • 首先,我们将 Student 类编码为 JSON 数据。
  • 然后,我们使用相同的 JSON 数据将其解码为 Student 类。

现在让我们看看例子。 

 
    1. import json
    2. from collections import namedtuple
    3. from json import JSONEncoder
    4. class Student:
    5.     def __init__(self, rollNumber, name, marks):
    6.         self.rollNumber, self.name, self.marks = rollNumber, name, marks
    7. class Marks:
    8.     def __init__(self, english, geometry):
    9.         self.english, self.geometry = english, geometry
    10. class StudentEncoder(JSONEncoder):
    11.         def default(self, o):
    12.             return o.__dict__
    13. def customStudentDecoder(studentDict):
    14.     return namedtuple('X', studentDict.keys())(*studentDict.values())
    15. marks = Marks(8274)
    16. student = Student(1"Emma", marks)
    17. # dumps() produces JSON in native str format. if you want to writ it in file use dump()
    18. studentJson = json.dumps(student, indent=4, cls=StudentEncoder)
    19. print("Student JSON")
    20. print(studentJson)
    21. # Parse JSON into an object with attributes corresponding to dict keys.
    22. studObj = json.loads(studentJson, object_hook=customStudentDecoder)
    23. print("After Converting JSON Data into Custom Python Object")
    24. print(studObj.rollNumber, studObj.name, studObj.marks.english, studObj.marks.geometry)

输出:

    1. Student JSON
    2. {
    3.     "rollNumber"1,
    4.     "name""Emma",
    5.     "marks": {
    6.         "english"82,
    7.         "geometry"74
    8.     }
    9. }
    10. After Converting JSON Data into Custom Python Object
    11. 1 Emma 82 74
    '
    运行

2.使用 types.SimpleNamespace 和 object_hook 将 JSON 转换为自定义 Python 对象

我们可以用types.SimpleNamespace作为 JSON 对象的容器。与命名元组解决方案相比,它具有以下优势:

  • 它的执行时间更少,因为它没有为每个对象创建一个类。
  • 它精确而简单。

在本例中,我们将使用types.SimpleNamespaceobject_hook将 JSON 数据转换为自定义 Python 对象。 

 
    1. from __future__ import print_function
    2. import json
    3. from json import JSONEncoder
    4. try:
    5.     from types import SimpleNamespace as Namespace
    6. except ImportError:
    7.     # Python 2.x fallback
    8.     from argparse import Namespace
    9. class Student:
    10.     def __init__(self, rollNumber, name, marks):
    11.         self.rollNumber, self.name, self.marks = rollNumber, name, marks
    12. class Marks:
    13.     def __init__(self, english, geometry):
    14.         self.english, self.geometry = english, geometry
    15. class StudentEncoder(JSONEncoder):
    16.         def default(self, o): return o.__dict__
    17. marks = Marks(8274)
    18. student = Student(1"Emma", marks)
    19. # dumps() produces JSON in native str format. if you want to writ it in file use dump()
    20. studentJsonData = json.dumps(student, indent=4, cls=StudentEncoder)
    21. print("Student JSON")
    22. print(studentJsonData)
    23. # Parse JSON into an custom Student object.
    24. studObj = json.loads(studentJsonData, object_hook=lambda d: Namespace(**d))
    25. print("After Converting JSON Data into Custom Python Object using SimpleNamespace")
    26. print(studObj.rollNumber, studObj.name, studObj.marks.english, studObj.marks.geometry)

输出:

    1. Student JSON
    2. {
    3.     "rollNumber"1,
    4.     "name""Emma",
    5.     "marks": {
    6.         "english"82,
    7.         "geometry"74
    8.     }
    9. }
    10. After Converting JSON Data into Custom Python Object using SimpleNamespace
    11. 1 Emma 82 74

3.使用 JSONDecoder 类的对象解码将 JSON 数据转换为自定义 Python 对象 

我们可以使用 json模块的json.JSONDecoder类来专门进行 JSON 对象解码,这里我们可以将 JSON 对象解码为自定义的 Python 类型。

我们需要在一个类中创建一个新函数,该函数将负责检查 JSON 字符串中的对象类型,在获取 JSON 数据中的正确类型后,我们可以构建我们的对象。

让我们看看例子。 

 
    1. import json
    2. class Student(object):
    3.     def __init__(self, rollNumber, name, marks):
    4.         self.rollNumber = rollNumber
    5.         self.name = name
    6.         self.marks = marks
    7. def studentDecoder(obj):
    8.     if '__type__' in obj and obj['__type__'] == 'Student':
    9.         return Student(obj['rollNumber'], obj['name'], obj['marks'])
    10.     return obj
    11. studentObj = json.loads('{"__type__": "Student", "rollNumber":1, "name": "Ault kelly", "marks": 78}',
    12.            object_hook=studentDecoder)
    13. print("Type of decoded object from JSON Data")
    14. print(type(studentObj))
    15. print("Student Details")
    16. print(studentObj.rollNumber, studentObj.name, studentObj.marks)
    '
    运行

输出:

    1. Type of decoded object from JSON Data
    2. <class '__main__.Student'>
    3. Student Details
    4. 1 Ault kelly 78

4.使用 jsonpickle 模块将 JSON 数据转换为自定义 Python 对象

jsonpickle 是一个 Python 库,旨在处理复杂的 Python 对象。你可以使用 jsonpickle 对复杂的 Python 和 JSON 数据进行序列化和反序列化。

Python 内置的 JSON 模块只能处理 Python 原语。对于任何自定义 Python 对象,我们都需要编写自己的 JSONEncoder 和 Decoder

使用 jsonpickle 我们将执行以下操作:

  • 首先,我们将使用 jsonpickle 将 Student 对象编码为 JSON
  • 然后我们将Student JSON解码成Student对象

现在,让我们看看将 JSON 数据转换为自定义 Python 对象的 jsonpickle 示例。

 
    1. import json
    2. import jsonpickle
    3. from json import JSONEncoder
    4. class Student(object):
    5.     def __init__(self, rollNumber, name, marks):
    6.         self.rollNumber = rollNumber
    7.         self.name = name
    8.         self.marks = marks
    9. class Marks(object):
    10.     def __init__(self, english, geometry):
    11.         self.english = english
    12.         self.geometry = geometry
    13. marks = Marks(8274)
    14. student = Student(1"Emma", marks)
    15. print("Encode Object into JSON formatted Data using jsonpickle")
    16. studentJSON = jsonpickle.encode(student)
    17. print(studentJSON)
    18. print("Decode and Convert JSON into Object using jsonpickle")
    19. studentObject = jsonpickle.decode(studentJSON)
    20. print("Object type is: "type(studentObject))
    21. print("Student Details")
    22. print(studentObject.rollNumber, studentObject.name, studentObject.marks.english, studentObject.marks.geometry)

输出:

    1. Encode Object into JSON formatted Data using jsonpickle
    2. {"marks": {"english"82"geometry"74"py/object""__main__.Marks"}, "name""Emma""py/object""__main__.Student""rollNumber"1}
    3. Decode JSON formatted Data using jsonpickle
    4. 1 Emma 82 74
    '
    运行

5.新建一个对象,将结果字典作为map传递,将JSON数据转换为自定义的Python对象

正如我们所知json.loads()json.load()方法返回一个dict对象。我们可以通过将dict对象作为参数传递给 Student 对象构造函数来构造一个新的自定义对象。即,我们可以将dict对象映射到自定义对象。

 
    1. import json
    2. from json import JSONEncoder
    3. class Student(object):
    4.     def __init__(self, rollNumber, name, *args, **kwargs):
    5.         self.rollNumber = rollNumber
    6.         self.name = name
    7. class StudentEncoder(JSONEncoder):
    8.         def default(self, o):
    9.             return o.__dict__
    10. student = Student(1"Emma")
    11. # encode Object it
    12. studentJson = json.dumps(student, cls=StudentEncoder, indent=4)
    13. #Deconde JSON
    14. resultDict = json.loads(studentJson)
    15. print("Converting JSON into Python Object")
    16. studentObj = Student(**resultDict)
    17. print("Object type is: "type(studentObj))
    18. print("Student Details")
    19. print(studentObj.rollNumber, studentObj.name)

输出:

    1. Converting JSON into Python Object
    2. Object type is:  <class '__main__.Student'>
    3. Student Details
    4. 1 Emma

总结

本文通过几种方法,介绍了Python如何将JSON转换为自定义Python对象/Python类。