Example of implementing JSON deserialization Class Object in Python, json serialization

Source: Internet
Author: User

Example of implementing JSON deserialization Class Object in Python, json serialization

Our network protocol is generally to convert data into JSON before transmission. Previously, serialization and deserialization were implemented in Java, both jackson and fastjson are very simple. Now there are projects that need to be developed using Python. it is natural to expect such convenience to be reflected in Python.

However, I have read some tutorials on the Internet. During deserialization, they are basically converted to dict or array. This programming method is emotionally unacceptable to me. Are these JSON databases not supported for deserialization into class objects? I immediately dismissed this idea. A powerful scripting language like Python cannot have a complete JSON library.

So I studied the native json, as well as the third-party demjson and simplejson.

I. Native json

I have carefully studied the definition of the native json loads method.

Copy codeThe Code is as follows:
Def loads (s, encoding = None, cls = None, object_hook = None, parse_float = None, parse_int = None, parse_constant = None, object_pairs_hook = None, ** kw)

The object_hook and object_pairs_hook parameters have aroused my attention. I will focus on object_hook.

The official documents are described as follows:

Object_hook is an optional function that will be called with the result of any object literal decoded (a dict ). the return value of object_hook will be used instead of the dict. this feature can be used to implement custom decoders (e.g. the JSON-RPC class hinting ).

This object_hook is interpreted as a custom decoding function according to the document. After standard deserialization of the input parameter dict, we can convert the output to the desired format according to our own rules.

I searched for object_hook again. The processing method for this item is to convert dict to an object using a static method.

Our data structure is like this.

{"Status": 1, "info": "published successfully", "data": {"id": "52", "feed_id": "70 "}}

So I wrote the following code:

class Response:  def __init__(self, status, info, data) -> None:    super().__init__()    self.status = status    self.info = info    self.data = data  @staticmethod  def object_hook(d):    return Response(d['status'], d['info'], d['data']) ...resp = json.loads(body, object_hook=Response.object_hook)

At the beginning, there was no problem. Although it was not convenient to use the java json library, it was always necessary.

The result is not long. In the data returned from the first interface I tested, data is a field string and deserialization is normal. However, when the data field returned by the interface is a dict structure, the input parameter of object_hook becomes the dict ({"id": "52 ", "feed_id": "70"}) instead of the complete data.

These attacks are hard, and there is no conclusion after the Internet searches. So I searched the internet and did not reach a conclusion. Okay, I will go back to the official document and read the fucking official document.

I don't know, but I was shocked. The official document uses a clever way to meet the above requirements.

>>> class JSONObject:...   def __init__(self, d):...     self.__dict__ = d...>>>>>> data = json.loads(s, object_hook=JSONObject)>>> data.name'ACME'>>> data.shares50>>> data.price490.1>>>

After I got it, I assigned the dict after json parsing to the property dict of the object. Then I can use the property as I like. It is really convenient and Dynamic Language is good.

The above is the official json library implementation solution. What about the other two well-known third-party libraries?

Ii. demjson

Demjson also supports hook. There are two Configuration Methods: decode function configuration and set_hook function configuration.

1. decode

def decode( txt, encoding=None, **kwargs )

The decode function can specify many parameters, including the hook function. The hook function specifies the key-value pair. The key is the name of the hook function and the value is the hook function.

Demjson manages hook functions by name. Therefore, hookname is not randomly specified and must be the name of Several built-in hook functions.

  1. Decode_number
  2. Decode_float
  3. Decode_object
  4. Decode_array
  5. Decode_string
  6. Encode_value
  7. Encode_dict
  8. Encode_dict_key
  9. Encode_sequence
  10. Encode_bytes
  11. Encode_default
demjson.decode(body, encode='utf-8',decode_obbject=Reponse.object_hook)

The results didn't make me very excited, and I still couldn't process the nested structure. The following content is displayed in the log:

16:01:17, 137 poster. py post_all 73 INFO: {"status": 1, "info": "\ u53d1 \ u5e03 \ u6210 \ u529f", "data": {"id": "54 ", "feed_id": "72 "}}
16:01:17, 138 response. py object_hook 13 INFO: {'id': '54', 'feed _ id': '72 '}
16:01:17, 138 response. py object_hook 13 INFO: {'status': 1, 'info': 'published successfully', 'data': demjson. undefined}

It is strange that the object_hook function is called twice. The first is the content of the data field, and the second is the whole content, but the data field is not parsed. It's very strange. You can't explain it !!!

2. set_hook

The set_hook function is different from the preceding decode function. It is a member function of the JSON class, And the decode function is a static function.

def set_hook(self, hookname, function)

I learned from my previous lessons. This time I carefully read the demjson document and found something.

Netsted values. when decoding JSON that has nested objects or arrays, the decoding hooks will be called once for every corresponding value, even if nested. generally the decoding hooks will be called from the inner-most value outward, and then left to right.

Here we will focus on nesting. When nesting occurs, each corresponding type will call the hook function once, and it is from the innermost layer, from left to right. Okay, all the problems that have occurred before are clear. It turns out that this rule has caused us, but I still don't understand why it is designed like this for the moment.

Set_hook usage

j = demjson.JSON()  j.set_hook( 'decode_array', my_sort_array )  j.decode(body, encode='utf-8')

Iii. simplejson

As mentioned above, there is nothing to say about the simplejson method, which is consistent with the official json library hook method.

Summary

Although my requirements are met, there is still a big question mark in my mind. Why is this design? I didn't find a proper answer on the Internet. The rest needs to be studied for source code analysis.

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.