Another method of JSON serialization

Posted by scritpkid on Sat, 05 Mar 2022 05:46:10 +0100

I said three methods of JSON serialization in Python yesterday.

Finally, I mentioned a method that can not only be directly JSON, but also be serialized in list, map or other uncontrollable frameworks. This is the following:

class Food(dict):
  def __init__(self, name, origin, calories, price):
    dict.__init__(self, name=name, origin=origin, calories=calories, price=price)    
    self.name = name 
    self.origin = origin 
    : .calories = calories 
    self.price = price 

  def to_json(self):
    return self.__dict__

print('...2500 lines of recommended algorithm code are omitted here...')
food1 = Food('soup with pepper', 'Shandong', 25, 2)
food2 = Food('Deep-Fried Dough Sticks', 'Shandong', 88, 1)
food3 = Food('Jellied bean curd', 'Shandong', 35, 2.5)
food4 = Food('braised flat bread', 'Shandong', 65, 10)

recommend = [food1, food2, food3, food4]


import json
recommend_json = json.dumps(recommend, indent=4, ensure_ascii=False)
print(recommend_json)

This method seems ideal, but a * * @ River * * put forward a fatal defect of this scheme!

Its disadvantages are:

If the attribute value is changed in the middle of the process, the original value will come out in the last dump. This is because the value of Food's parent class dict is determined in the first line of Food constructor, and the change of attribute value will not affect the value in dict.

Take an example:

food1 = Food('soup with pepper', 'Shandong', 25, 2)
food1.price = 999
print(json.dumps(food1, indent=4, ensure_ascii=False))

The price of food1 is 2, which was later changed to 999, but the result of dumps is still 2:

{
    "name": "soup with pepper",
    "origin": "Shandong",
    "calories": 25,
    "price": 2
}

In other words, this method can only be used for objects whose values will not change once initialized.

No solution!

It's over. There's no solution.

To achieve the ideal goal, there seems to be no solution!

The ideal approach is:

1. The object can be directly used with JSON Dumps (obj) serialization

2. Objects can be serialized in data structures such as list

3. Objects can still be serialized after being passed to other frameworks or programs beyond our control

I have studied all kinds of relevant discussions in the Chinese world and the English world. At least I haven't found an ideal solution.

If the mountain doesn't come, I'll go

Since it is impossible to serialize objects directly in the list, in order to serialize, we have to accommodate the json library, convert objects into dictionaries and then pass them to it.

Here we need to use a function called vars(), which can return all the properties of the current object in the form of a dictionary.

Look at the code:

class Food(dict):
  def __init__(self, name, origin, calories, price):
    dict.__init__(self, name=name, origin=origin, calories=calories, price=price)    
    self.name = name 
    self.origin = origin 
    self.calories = calories 
    self.price = price 

  def to_json(self):
    return self.__dict__

food1 = Food('soup with pepper', 'Shandong', 25, 2)
food2 = Food('Deep-Fried Dough Sticks', 'Shandong', 88, 1)
food3 = Food('Jellied bean curd', 'Shandong', 35, 2.5)
food4 = Food('braised flat bread', 'Shandong', 65, 10)
food1.price = 999

recommend = [vars(food1), vars(food2), vars(food3), vars(food4)]

import json
recommend_json = json.dumps(recommend, indent=4, ensure_ascii=False)
print(recommend_json)

The point here is that when building the recommend dictionary, vars(foodx) is passed in instead of the object directly. This is: if the mountain doesn't come, I'll go.

Looking at the results, the new price 999 can be successfully serialized:

[
    {
        "name": "soup with pepper",
        "origin": "Shandong",
        "calories": 25,
        "price": 999
    },
    {
        "name": "Deep-Fried Dough Sticks",
        "origin": "Shandong",
        "calories": 88,
        "price": 1
    },
    {
        "name": "Jellied bean curd",
        "origin": "Shandong",
        "calories": 35,
        "price": 2.5
    },
    {
        "name": "braised flat bread",
        "origin": "Shandong",
        "calories": 65,
        "price": 10
    }
]

Just like life, many things seem to have no solution. In fact, it is because we fall into the thinking pattern. There are always ways to break the thinking pattern.

Share another story that happened to me last week:

We have a project that aims to go online by the end of March. Team members say it's impossible. It can't be those who are particularly active, self-motivated and experienced, which shows that it is really difficult.

I said: think again, there will always be a way.

It was soon suggested that some functions could be cut off for the time being. Based on this assumption, everyone came up with ideas and made a plan to go online before the end of March within half an hour.

This is also an example of breaking the mindset. It is said that we will go online at the end of March. In order to achieve this goal, we can adjust other variables, such as increasing resources, reducing scope, and of course, working overtime.

Today's thinking is a little diffuse. The above example can lead to some knowledge points of project management:

  • Three elements of project management: scope, resources and time. This is the knowledge in books and on the roadside. The following is my experience for many years.
  • When the three elements conflict, we should try to keep the time unchanged and adjust the resources and scope. Because it goes online on time, it's better to finish less than not to finish, or to increase investment too much.

Recommended reading

My cousin said that this Python regular task can earn 5000. Do you believe me?

Topics: Python Back-end