简体   繁体   English

Python 对象的 JSON 序列化是否有约定?

[英]Is there a convention for JSON serialization of Python objects?

Is there a convention for JSON-serializing (and deserializing) Python objects to identify the object type?是否有 JSON 序列化(和反序列化)Python 对象的约定来识别 object 类型? I've gone through this example solution below (which I find quite decent with slight modification), but I still wonder: is any safety concern and is it crystal-clear enough?我已经浏览了下面的这个示例解决方案(我发现它经过轻微修改后相当不错),但我仍然想知道:是否存在任何安全问题,它是否足够清晰?

Result (Note the addition of the __type__ attribute)结果(注意添加了 __type__ 属性)

{
  "__type__": "date",
  "year": 2022,
  "month": 1,
  "day": 1
}

is printed from the following code:从以下代码打印:

import json
from datetime import date, timedelta

class MyJSONEncoder(json.JSONEncoder):

    def default(self, obj):
        if isinstance(obj, date):
            return {
                '__type__' : 'date',
                'year' : obj.year,
                'month' : obj.month,
                'day' : obj.day
            }   

        elif isinstance(obj, timedelta):
            return {
                '__type__' : 'timedelta',
                'days' : obj.days,
                'seconds' : obj.seconds,
                'microseconds' : obj.microseconds,
            }   
        # And more and more classes to support
        else:
            return super().default(self, obj)

class MyJSONDecoder(json.JSONDecoder):

    SUPPORTING_TYPES = {'date': date, 'timedelta': timedelta}

    def __init__(self):
            super().__init__(object_hook=self.dict_to_object)

    def dict_to_object(self, d): 

        if '__type__' in d and d['__type__'] in self.SUPPORTING_TYPES:
            obj_type = self.SUPPORTING_TYPES[d.pop('__type__')]
            return obj_type(**d)
        return d

# And to encode / decode

d = date(2022,1,1)
serialized_d = json.dumps(d, cls=MyJSONEncoder)
print(serialized_d)
d_ = json.loads(serialized_d, cls=MyJSONDecoder)

assert d == d_ # Assertion check

Your methodology seems reasonable enough to me.你的方法对我来说似乎足够合理。 However if I were working on a similar project I would try to simplify it as much as possible in order to simplify both ends of the serialization process.但是,如果我在做一个类似的项目,我会尽量简化它,以简化序列化过程的两端。

For example, I wouldn't break down datetime objects into years months and days, Instead I would store it in either timestamp or isoformat depending on how readable I needed it to be.例如,我不会将 datetime 对象分解为年月和日,而是将它存储在时间戳或 isoformat 中,具体取决于我需要它的可读性。 This would make converting to json as easy as date_time_obj.isoformat() and converting back to datetime would be datetime.fromisoformat() .这将使转换为 json 像date_time_obj.isoformat()一样简单,转换回 datetime 将是datetime.fromisoformat()

The same goes for TimeDelta. TimeDelta 也是如此。 Depending on how readable it needs to be I would just store the whole delta as seconds, which would reduce the number of items to parse and would reduce the serializing code to timedelta.total_seconds() and timedelta(seconds=arg) .根据它需要的可读性,我只需将整个增量存储为秒,这将减少要解析的项目数量并将序列化代码减少到timedelta.total_seconds()timedelta(seconds=arg) Very large deltas would be difficult to read though.但是,非常大的增量将难以阅读。

All that being said... your method is pretty simple as it is, so I would say the difference is completely subjective.话虽如此……您的方法很简单,所以我想说差异是完全主观的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM