Arquivo

Posts Tagged ‘simplejson’

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

Categorias:datetime, Python Tags:, ,