首页 > 解决方案 > 指示将 JSON 字符串反序列化为 Object 的类类型

问题描述

我正在尝试将 JSON 字符串反序列化为 Python 中的对象,同时指示每个对象的特定类类型。这是一个示例 JSON:

{
    "Vehicle":
    [
        {
            "$type": "Car",
            "Make": 1982,
            "Settings":
            {
                "$type": "CarSettings",
                "ESP": true
            }
        },
        {
            "$type": "Motorcycle",
            "Make": 2010,
            "Settings":
            {
                "$type": "MotorcycleSettings",
                "ABS": true
            }
        }
    ]
}

请注意,我的课程是这样构建的:

和:

我想出了一个使用“json.loads”和“object_hook”来表示整个JSON的单一类型,但我似乎无法让它适用于子类。

谢谢!

标签: pythonjson

解决方案


您定义的object_hook将从 JSON 字符串中获取字典。举个例子:

def hook(dic):
  print(dic)
  return dic

使用它作为一个钩子,你的例子将产生:

{'$type': 'CarSettings', 'ESP': True}
{'$type': 'Car', 'Make': 1982, 'Settings': {'$type': 'CarSettings', 'ESP': True}}
{'$type': 'MotorcycleSettings', 'ABS': True}
{'$type': 'Motorcycle', 'Make': 2010, 'Settings': {'$type': 'MotorcycleSettings', 'ABS': True}}

因此,在hook()函数中,您采用$type元素并按照该元素行事。

def hook(dic):
  if dic['$type'] == "Car":
     return Car(**dic) # assuming Car constructor can take kwargs
  if dic['$type'] == "Motorcycle":
     return Motorcycle(**dic) # assuming Motorcycle constructor can take kwargs

hook()首先在最嵌套的字典上调用。因此,如果您解析CarSettings并从 中返回该对象,hook()则 Car ( '$type': 'Car') 的字典将已经包含CarSettings类型对象。

{'$type': 'Car', 'Make': 1982, 'Settings': <__main__.CarSettings object at 0x000001FF4FD6A550>}

如果您有许多类,请制作一个字典,为类型名排序类型,并将其用于创建对象。

types = {
  'Car' : Car,
  'Motorcycle' : Motorcycle,
}

def hook(dic):
  try:
     return types[dic['$type']](**dic)
  except KeyError:
     pass

推荐阅读