Десериализуйте строку json к объекту в Python

У меня есть следующая строка

{"action":"print","method":"onData","data":"Madan Mohan"}

Я Хочу десериализовать к объекту класса

class payload
    string action
    string method
    string data

Я использую python 2.6 и 2.7

59
задан 18 March 2013 в 16:37

3 ответа

В последних версиях Python можно использовать зефир-dataclass :

from marshmallow_dataclass import dataclass

@dataclass
class Payload
    action:str
    method:str
    data:str

Payload.Schema().load({"action":"print","method":"onData","data":"Madan Mohan"})
3
ответ дан 1 November 2019 в 11:10

В то время как Alex ответ указывает на нас на хорошую технику, реализация, которую он дал, сталкивается с проблемой, когда у нас есть вложенные объекты.

class more_info
    string status

class payload
    string action
    string method
    string data
    class more_info

с ниже кода:

def as_more_info(dct):
    return MoreInfo(dct['status'])

def as_payload(dct):
    return Payload(dct['action'], dct['method'], dct['data'], as_more_info(dct['more_info']))

payload = json.loads(message, object_hook = as_payload)

payload.more_info будет также рассматриваться как экземпляр payload, который приведет к ошибкам анализа.

Из официальных документов:

object_hook является дополнительной функцией, которая будет вызвана с результатом любого декодируемого литерала объектов (dict). Возвращаемое значение object_hook будет использоваться вместо dict.

Следовательно, я предпочел бы предлагать следующее решение вместо этого:

class MoreInfo(object):
    def __init__(self, status):
        self.status = status

    @staticmethod
    def fromJson(mapping):
        if mapping is None:
            return None

        return MoreInfo(
            mapping.get('status')
        )

class Payload(object):
    def __init__(self, action, method, data, more_info):
        self.action = action
        self.method = method
        self.data = data
        self.more_info = more_info

    @staticmethod
    def fromJson(mapping):
        if mapping is None:
            return None

        return Payload(
            mapping.get('action'),
            mapping.get('method'),
            mapping.get('data'),
            MoreInfo.fromJson(mapping.get('more_info'))
        )

import json
def toJson(obj, **kwargs):
    return json.dumps(obj, default=lambda j: j.__dict__, **kwargs)

def fromJson(msg, cls, **kwargs):
    return cls.fromJson(json.loads(msg, **kwargs))

info = MoreInfo('ok')
payload = Payload('print', 'onData', 'better_solution', info)
pl_json = toJson(payload)
l1 = fromJson(pl_json, Payload)

1
ответ дан 1 November 2019 в 11:10

Существуют различные методы для десериализации строки json к объекту. Все выше методов приемлемы, но я предлагаю пользоваться библиотекой, чтобы предотвратить дублирующиеся ключевые вопросы или сериализировать/десериализовать вложенных объектов.

Pykson, Serializer JSON и Deserializer для Python , который может помочь Вам достигнуть. Просто определите модель класса Полезной нагрузки, поскольку JsonObject затем используют Pykson для преобразования строки json для возражения.

from pykson import Pykson, JsonObject, StringField

class Payload(pykson.JsonObject):
    action = StringField()
    method = StringField()
    data = StringField()

json_text = '{"action":"print","method":"onData","data":"Madan Mohan"}'
payload = Pykson.from_json(json_text, Payload)
1
ответ дан 1 November 2019 в 11:10

Другие вопросы по тегам:

Похожие вопросы: