0
点赞
收藏
分享

微信扫一扫

JSON序列化的另外一种方法

嚯霍嚯 2022-03-11 阅读 89

昨天的3分钟我说了3种用Python做JSON序列化的方法。

最后提到了一种不仅自己可以直接被JSON化,还可以在list, map或者其他自己不可控的框架中被序列化的方法。就是下面这种:

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行推荐算法代码...')
food1 = Food('胡辣汤', '山东', 25, 2)
food2 = Food('油条', '山东', 88, 1)
food3 = Food('豆腐脑', '山东', 35, 2.5)
food4 = Food('焖饼', '山东', 65, 10)

recommend = [food1, food2, food3, food4]


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

这种方法看似比较理想,但是有位**@江河**提出了这个方案的一个致命缺陷!

它的缺陷在于:

看个例子:

food1 = Food('胡辣汤', '山东', 25, 2)
food1.price = 999
print(json.dumps(food1, indent=4, ensure_ascii=False))

food1的价格是2,后来被改成了999,但是dumps出来的结果还是2:

{
    "name": "胡辣汤",
    "origin": "山东",
    "calories": 25,
    "price": 2
}

也就是说,这种方法只能用于值一旦初始化就不会改变的对象。

无解了!

完了,无解了。

要实现理想的目标,似乎是无解了!

我研究过中文世界和英文世界里的各种相关讨论,至少我没有找到一种理想的解决方法。

山不过来,我就过去

既然无法让对象直接在列表中序列化,为了做序列化,就只好迁就json库,把对象都转成字典再传给它。

这里要用到一个函数叫做:vars(),它可以以字典的形式返回当前对象中所有的属性。

看代码:

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('胡辣汤', '山东', 25, 2)
food2 = Food('油条', '山东', 88, 1)
food3 = Food('豆腐脑', '山东', 35, 2.5)
food4 = Food('焖饼', '山东', 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)

这里的要点在于,构建recommend字典的时候传入的是vars(foodx)而不是直接传入对象,这就是:山不过来,我就过去

看看结果,新的价格999可以被成功序列化:

[
    {
        "name": "胡辣汤",
        "origin": "山东",
        "calories": 25,
        "price": 999
    },
    {
        "name": "油条",
        "origin": "山东",
        "calories": 88,
        "price": 1
    },
    {
        "name": "豆腐脑",
        "origin": "山东",
        "calories": 35,
        "price": 2.5
    },
    {
        "name": "焖饼",
        "origin": "山东",
        "calories": 65,
        "price": 10
    }
]

就像人生一样,很多东西看似是无解的,其实是因为我们陷入了思维定式,打破思维定式,办法总是有的。

再分享一个上周发生在我身边的故事吧:

这也是一个打破思维定式的例子,说了要3月底上线,为了实现这个目标,我们可以调整其他变量,比如增加资源,减少范围,当然也包括加班加点。

今天的思维有点扩散,上面的例子可以引出一点项目管理的知识点:

  • 项目管理的3个要素:范围,资源和时间。这是书本上的,大路边的知识,下面这个点我多年的心得体会。
  • 当3要素出现冲突的时候,我们要尽量保持时间不变,调整资源和范围。因为按时上线,完成的少一点,要好过没有完成,也好过过多的增加投入。

推荐阅读

举报

相关推荐

0 条评论