Inicial > datetime, Python > Transformando objetos python complexos em JSON

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:, ,
  1. 25/07/2014 às 14:37

    Ó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/)

  1. No trackbacks yet.

Deixe um comentário