У меня есть следующая строка
{"action":"print","method":"onData","data":"Madan Mohan"}
Я Хочу десериализовать к объекту класса
class payload
string action
string method
string data
Я использую python 2.6 и 2.7
В последних версиях 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"})
В то время как 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)
Существуют различные методы для десериализации строки 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)