JSON Serialization in Python
In C#, it is really easy to convert between class and JSON object, which brings tremendous convenience for Web development. Recently, I have to use a Python framework Django, and found that there’s no such feature as C#, so I implemented a shabby replica for that by myself.
What you will learn
In this article, you will get both a serializer and a de-serializer in Python to convert JSON string or
dict
object into or from a Python object. 😋
Prerequisites
To start with, you must keep one concept in mind,
"Python object is merely a dictionary!"
Not that absolute, but generally speaking, yes.
We do not begin with scratch, and Python already make json
package part of its standard. So we just use it for fundamental parsing.
Let’s Start Serialization!
1. JSON Encoder & Decoder
For basic conversion between JSON string and Python dict
, we can simply use json
module to do the stuffs. However, if you have datetime
field in your Python object, you have to manually convert it to string, as JSON doesn’t have corresponding datetime value.
When you use json.dump
, you need a custom encoder to handle datetime
field.
1 | class AdvancedEncoder(json.JSONEncoder): |
Notice that,
datetime
is derived fromdate
, so you should place instance check ofdatetime
ahead ofdate
. And the format is custom, just make sure they corresponds each other in Encoder and Decoder. 🫡
Then, correspondingly, when you use json.loads
, you need a custom decoder. However, what is different is that we need to override its object_hook
to tell it to try convert str
into datetime
object. (It seems, in previous version, it is a method, instead of a member.)
1 | def object_hook(obj): |
2. Serialization
Then, with JSONEncoder
, you can simply serialize a object into JSON string.
1 | def serialize(obj) -> str: |
Serialization related exceptions will be talked about at the end, since they are not the main topic.
If you don’t want to serialize a object into raw string, you can also serialize it into a dict
.
1 | def serialize_as_dict(obj) -> dict: |
Well, I guess you can also achieve this by serialize it first into a string, then deserialize it into a
dict
, which will then need no extra work.
3. Deserialization
Compared to serialization, deserialization got one more problem - how to deserialize deserialize a JSON object into a object with desired class? And this is the key point of the article.
Then, the deserialization can be implemented as such. If cls
is assigned, it will try to convert JSON string or object into the given class. Otherwise, it will simply return a dict
object.
1 | def deserialize(obj, cls=None): |
There are two functions that play an important role here, _check_type
and _construct_cls
. They make sure the JSON object strictly match the given class, and try to build such a class from the JSON object. The implementation of them may be a little hard to understand, though. 😣
1 | def _check_type(dict_obj, cls_obj) -> bool: |
So… again, Python object is just a dict
with some extra fields. Emm… Hope it could make it easier for you to understand the code. 🥺
4. Exception Declaration
At last, I present to you the definition of custom exceptions that I used to fit the last piece.
1 | class JsonException(Exception): |
So, this is it. And… I guess that Python is not that diabolical. It can be convenient sometimes. Only, some times. 😶🌫️