Transformando objetos python complexos em JSON
Olá pessoal,
como vocês devem saber, hoje em dia retornar um objeto JSON em qualquer tipo de serviço tornou-se meio que uma obrigação. Pois bem, em Python existe um pacote muito simples para converter dicionários (dict) em JSON chamado simplejson.
import simplejson my_obj = dict(name="Nameless Terror") my_obj_json = simplejson.dumps(my_obj)
Se você der um inspect no object, verá que o seguinte resultado:
‘{“name”: “Nameless Terror”}’
Lindo não? Pois bem, e se ao invés de termos um dicionário, tivermos um objeto python complexo?
import simplejson class MyComplexObject(object): def __init__(self, name): self.name = name my_complex_obj = MyComplexObject("Nameless Terror") my_complex_obj_json = simplejson.dumps(my_complex_obj)
Você deve ter notado que ao executar esse código acima, um erro foi lançado:
TypeError: <__main__.MyComplexObject object at 0x102e1ed10> is not JSON serializable
Isso ocorreu pois o simplejson não tem idéia de como converter esse objeto. Uma forma simples de resolver isso seria simplesmente chamar o atributo __dict__ do objeto e passá-lo para o simplejson que no fim o transformaria sem problema, mas e se além do atributo name tivessemos um atributo creation_date que receberia um objeto datetime? Ou até mesmo uma tivessemos uma lista com vários objetos desconhecidos? o.O Teriámos que iterar por todos os atributos e chamar o __dict__ de cada um deles? Lembrando que o datetime não possui __dict__! PÂNICO! o.O
Calma, método dumps do simplejson recebe um parâmetro chamado defualt que nada mais é que uma função que é chamada quando ele não sabe como transformar em json um objeto qualquer.
import simplejson import datetime def default_parser(obj): if getattr(obj, "__dict__", None): return obj.__dict__ elif type(obj) == datetime: return obj.isoformat() else: return str(obj) class MyComplexObject(object): def __init__(self, name, other_object=None): self.name = name self.creation_date = datetime.datetime.now() self.other_object = other_object my_other_complex_obj = MyComplexObject("Just to mess") my_complex_obj = MyComplexObject("Nameless Terror", my_other_complex_obj) my_complex_obj_json = simplejson.dumps(my_complex_obj, default=default_parser)
Se inspecionarmos agora o objeto my_complex_obj_json:
‘{“other_object”: {“other_object”: null, “name”: “Just to mess”, “creation_date”: “2014-07-24 15:43:26.515125”}, “name”: “Nameless Terror”, “creation_date”: “2014-07-24 15:43:26.518914”}’
Lindo não? =D
Pois então, espero que vocês curtam aí a dica, me de um trabalhinho até chegar nessa solução aí! 😉
[]’s
Ótima dica!
(Ah, use as tags de marcação de código-fonte que o wordpress fornece para mostrar exemplos de código. Assim, ele já faz o syntax highlighting, numeração de linhas e tudo mais: http://en.support.wordpress.com/code/posting-source-code/)
Opa,
valeu mesmo pela dica! 😉