Serialize Object to JSON

5

How do I convert an object to JSON?

I even found some codes on the internet that even worked, but my object has some fields that are other objects and then the conversion did not reach the last level.

Example:

class Pessoa(object):
    codigo = 0
    nome = ''
    endereco = Endereco()

class Endereco(object):
    codigo = 0
    logradouro = ''
    bairro = ''
    cidade = Cidade()

class Cidade(object):
    codigo = 0
    nome = ''
    uf = ''

These are my objects, but by doing the conversion I found, the JSON result comes only with the values contained in Person in Address , then City from outside of JSON:

{
    'codigo': 1,
    'nome': 'Oliveira',
    'endereco': {
        'codigo': 5,
        'logradouro': 'Rua A',
        'bairro': 'Campos'            
    }
}

That is, I believe the code did not go through all levels.

I'm using pyMongo and I saw that you have a bson library that has some conversions but I did not know how to use it or else it does not do what I need.

    
asked by anonymous 09.07.2016 / 02:23

2 answers

2
So, in Python, there is the type of data Dictionary that is type Map of other languages, it is a structure of (key, value) , that is, almost like the problem that you need, because the Json format follows this (key, value) pattern.
Here is an example below of a use of this structure that already comes in the language and does not need other packages and modules, however you must adapt to its use there, obviously:

Pessoa = {}
Endereco = {}
Cidade = {}

Endereco['Logradouro'] = "Rua A"
Endereco['Numero'] = 80
Endereco['Bairro'] = "Centro"

Cidade['Nome'] = "Belo Horizonte"
Cidade['UF'] = "Minas Gerais"
Cidade['Codigo'] = 0

Pessoa['Nome'] = "Meu nome é esse"
Pessoa['Codigo'] = 1
Pessoa['Endereco'] = Endereco
Pessoa['Cidade'] = Cidade

print(repr(Pessoa))

Result

{
    "Nome": "Meu nome é esse",
    "Codigo": 1,
    "Endereco": {
        "Numero": 80,
        "Logradouro": "Rua A",
        "Bairro": "Centro"
     },
    "Cidade": {
        "Nome": "Belo Horizonte",
        "Codigo": 0,
        "UF": "Minas Gerais"
     }
}

Then you can make a class that assembles these dictionaries separately, using the methods of accessing its objects, and with the repr(obj) method that already returns you the json you need, is solved your problem.

    
09.07.2016 / 04:01
4

First, you need to define your fields within __init__ , and not so in the class, otherwise they will be shared by all instances of the class (ie they will be "static") instead of having one each object:

class Pessoa(object):
    def __init__(self):
        self.codigo = 0
        self.nome = ''
        self.endereco = Endereco()

class Endereco(object):
    def __init__(self):
        self.codigo = 0
        self.logradouro = ''
        self.bairro = ''
        self.cidade = Cidade()

class Cidade(object):
    def __init__(self):
        self.codigo = 0
        self.nome = ''
        self.uf = ''

(You can place parameters - optional or required - in the constructor if you want, instead of starting everything with a default value, just be careful with default values that are also objects, putting it in the signature of the method will bring unwanted effects)

You often do not need classes - use literals for dict , or create them by yourself (such as suggested by Christian Felipe ) may be enough. However, classes can be useful if you intend to give them methods, so do not say not to use, use yes if necessary / convenient.

Once this is done, the object / json conversion libraries you have tried should give the correct result. But if you want a simple method to do by hand, you can take advantage of the fact that the __dict__ field of an object transforms its properties into fields of a dict :

import json

def para_dict(obj):
    # Se for um objeto, transforma num dict
    if hasattr(obj, '__dict__'):
        obj = obj.__dict__

    # Se for um dict, lê chaves e valores; converte valores
    if isinstance(obj, dict):
        return { k:para_dict(v) for k,v in obj.items() }
    # Se for uma lista ou tupla, lê elementos; também converte
    elif isinstance(obj, list) or isinstance(obj, tuple):
        return [para_dict(e) for e in obj]
    # Se for qualquer outra coisa, usa sem conversão
    else: 
        return obj

p = Pessoa()
s = json.dumps(para_dict(p))

This should work for the most common cases, and using json.dumps ensures that at least nothing invalid will be echoed to the output.

    
09.07.2016 / 04:46