JSON Advanced
Python's dict object can be serialized directly into JSON's {}, but many times, we prefer to use class to represent objects, such as defining Student class and then serializing:
import json class Student(object): def __init__(self, name, age, score): = name = age = score s = Student('Bob', 20, 88) print((s))
Run the code and get a TypeError without mercy:
Traceback (most recent call last): ... TypeError: <__main__.Student object at 0x10aabef50> is not JSON serializable
The reason for the error is that the Student object is not a serializable object to JSON.
If even the instance object of class cannot be serialized to JSON, this is definitely unreasonable!
Don't worry, let's take a closer look at the parameter list of dumps() method and find that in addition to the first necessary obj parameter, dumps() method also provides a lot of optional parameters:
/2/library/#
These optional parameters are for us to customize JSON serialization. The reason why the previous code cannot serialize Student class instances to JSON is that by default, the dumps() method does not know how to turn Student instances into a JSON {} object.
The optional parameter default is to turn any object into an object that can be sequenced as JSON. We only need to write a conversion function specifically for Student and then pass the function in:
def student2dict(std): return { 'name': , 'age': , 'score': } print((s, default=student2dict))
In this way, the Student instance is first converted to dict by the student2dict() function, and then it is successfully serialized to JSON.
However, next time if you encounter an instance of Teacher class, it still cannot be serialized to JSON. We can be lazy and turn any class instance into dict:
print((s, default=lambda obj: obj.__dict__))
Because usually the instance of class has a __dict__ attribute, it is a dict, which is used to store instance variables. There are a few exceptions, such as class that defines __slots__.
By the same token, if we want to deserialize JSON into a Student object instance, the loads() method first converts a dict object, and then the object_hook function we passes in is responsible for converting dict to a Student instance:
def dict2student(d): return Student(d['name'], d['age'], d['score']) json_str = '{"age": 20, "score": 88, "name": "Bob"}' print((json_str, object_hook=dict2student))
The operation results are as follows:
<__main__.Student object at 0x10cd3c190>
What is printed is the deserialized Student instance object.
summary
The Python language-specific serialization module is pickle, but if you want to make serialization more general and more compliant with web standards, you can use the json module.
The dumps() and loads() functions of the json module are examples of very well-defined interfaces. When we use it, we only need to pass in one necessary parameter. However, when the default serialization or deserialization mechanism does not meet our requirements, we can pass in more parameters to customize the serialization or deserialization rules, which not only makes the interface simple and easy to use, but also achieves full scalability and flexibility.