Python Iluminado

JSON

Na computação, JSON ou Javascript Object Notation é um padrão aberto de formato de arquivo que utiliza textos legíveis para humanos para transmistir objetos de dados que consistem de pares de atributos-valores e tipos de dados array (ou qualquer outro valor serializável), é um formato de dados de uso muito comum para comunicação asíncrona de cliente-servidor.

É importante destacar, que embora JSON carregue Javascript no seu nome, ele é independente e vale para qualquer linguagem de programação.

Os tipos básicos de dados do JSON são:

  • Number: Um número decimal com sinal que pode conter uma parte fracionária e pode usar a notação exponencial E, mas não pode incluir não-números como NaN. O formato não faz distinção entre integer e floating-point.
  • String: Uma sequência de zero ou mais caracteres Unicode. Strings são delimitadas com aspas duplas e oferecem suporte a uma sintaxe de escape de barra invertida.
  • Boolean: Um valor true ou false
  • Array: Uma lista ordenada de zero ou mais valores, cada um dos quais pode ser de qualquer tipo. Arrays usam notação de colchetes com elementos separados por vírgula.
  • Object: Uma coleção de pares nome-valor onde os nomes (também chamados de chaves) são strings. Os objetos têm o objetivo de representar arrays associativos, onde cada chave é única dentro de um objeto. Os objetos são delimitados por chaves e usam vírgulas , para separar cada par, enquanto dentro de cada par o caractere : separa a chave ou nome de seu valor.
  • null: Um valor vazio, utilizando a palavra null

Para entendermos melhor o JSON, vamos definir um arquivo pessoa.json que descreverá uma pessoa:

{
"primeiroName": "Miguel",
"segundoName": "Arcanjo",
"estaVivo": true,
"idade": 27,
"endereço": {
"rua": "Rua Alfa 33",
"cidade": "São Paulo",
"estado": "SP",
"codigoPostal": "1321-32423"
},
"numerosTelefones": [
{
"tipo": "casa",
"numero": "212 555-1234"
},
{
"tipo": "escritorio",
"numero": "646 555-4567"
},
{
"tipo": "celular",
"numero": "123 456-7890"
}
],
"criancas": [],
"cônjuge": null
}

Como podermos ver, JSON é bastante legível e acessível, fazendo com que seja excelente para estruturarmos dados, nesse caso, veja que temos um objeto pessoa.

Dentro do objeto pessoas temos diversos atributos:

  • primeiroName: String representando o primeiro nome da pessoa
  • segundoName: String representando o sobrenome da pessoa
  • estaVivo: Boolean representando se a pessoa está viva ou não
  • idade: Number integer representando a idade da pessoa
  • endereço: Um objeto com quatro atributos (rua, cidade, estado, codigoPostal) representando o endereço da pessoa
  • numerosTelefones: Um array contendo três objetos, representando os telefones da pessoa
  • criancas: Um array representando as crianças da pessoa, neste exemplo ele está vazio
  • cônjuge: Campo representando se a pessoa é casada, neste exemplo está null

Para utilizarmos JSON em Python, contamos com o módulo json, que podemos importá-lo facilmente, sem a necessida de instalação:

import json

Parse de JSON, Convertendo JSON para Python

Em Python, caso tenhamos uma string JSON, nós usamos o método json.loads() para fazer o parse e convertermos em um dicionário para que seja mais fácil de trabalharmos com os dados.

Veja que além do arquivo .json, também podemos ter JSON armazenado como uma string:

import json
pessoa = '{ "nome":"Rafael", "idade":29, "cidade":"São Paulo"}'
pessoa_dict = json.loads(pessoa)
print(type(pessoa_dict)) # <class 'dict'>
print(pessoa_dict) # {'nome': 'Rafael', 'idade': 29, 'cidade': 'São Paulo'}
print(pessoa_dict['idade']) # 29

Convertendo Python para JSON

Se quisermos, também podemos converter um objeto de Python em uma string JSON, para esta tarefa vamos usar o método json.dumps().

Vamos definir um dicionário Python e fazer sua conversão:

import json
pessoa = {
"nome": "Gabriel",
"idade": 27,
"país": "Brasil"
}
pessoa_json = json.dumps(pessoa) # <class 'str'>
print(pessoa_json) # {"nome": "Gabriel", "idade": 27, "pa\u00eds": "Brasil"}

Perceba que ele não nos retornou os dados na codificação correta, para obtermos os dados em UTF-8, devemos setar o atributo ensure_ascii como False:

pessoa_json = json.dumps(pessoa, ensure_ascii=False)
print(pessoa_json) # '{"nome": "Gabriel", "idade": 27, "país": "Brasil"}'

É possível converter os seguintes objetos em Python para JSON, e eles receberão um valor de equivalência em JSON como mostra a seguinte tabela:

PythonJSON
dictObject
listArray
tupleArray
strString
intNumber
floatNumber
Truetrue
Falsefalse
Nonenull

Exemplo com todos os Tipos de Dados

Para compreendermos melhor o funcionamento da biblioteca json, vamos agora trabalhar em um exemplo contendo todos os tipos possíveis de dados.

import json
personagem = {
"nome": "Talantyr",
"epiteto": "O Glorioso",
"nível": 45,
"vivo": True,
"atributos": {"força": 45, "destreza": 60, "inteligência": 70},
"mascotes": ("Lobo","Coruja"),
"magias": None,
"itens": [
{"nome": "poção de mana", "quantidade": 5},
{"nome": "poção de vida", "quantidade": 7}
]
}
print(json.dumps(personagem, ensure_ascii=False))
# {"nome": "Talantyr", "epiteto": "O Glorioso", "nível": 45, "vivo": true, "atributos": {"força": 45, "destreza": 60, "inteligência": 70}, "mascotes": ["Lobo", "Coruja"], "magias": null, "itens": [{"nome": "poção de mana", "quantidade": 5}, {"nome": "poção de vida", "quantidade": 7}]}

Para obtermos um output mais limpo, podemos setar o atributo indent com um determinado número, neste caso específico, 4:

print(json.dumps(personagem, ensure_ascii=False, indent=4))

Dessa vez, temos o resultado que esperamos:

{
"nome": "Talantyr",
"epiteto": "O Glorioso",
"nível": 45,
"vivo": true,
"atributos": {
"força": 45,
"destreza": 60,
"inteligência": 70
},
"mascotes": [
"Lobo",
"Coruja"
],
"magias": null,
"itens": [
{
"nome": "poção de mana",
"quantidade": 5
},
{
"nome": "poção de vida",
"quantidade": 7
}
]
}

Caso queiramos os atributos do resultado ordenados, podemos usar o parâmetro sort_keys como True:

print(json.dumps(p, indent=4, sort_keys=True))

Dessa vez, temos o seguinte resultado:

{
"atributos": {
"destreza": 60,
"força": 45,
"inteligência": 70
},
"epiteto": "O Glorioso",
"itens": [
{
"nome": "poção de mana",
"quantidade": 5
},
{
"nome": "poção de vida",
"quantidade": 7
}
],
"magias": null,
"mascotes": [
"Lobo",
"Coruja"
],
"nome": "Talantyr",
"nível": 45,
"vivo": true
}

Se quisermos, podemos facilmente converter o dicionário personagem em JSON (como já vimos anteriormente) e em seguida, salvar os dados em um arquivo de nome personagem.json:

dados_json = json.dumps(personagem, ensure_ascii=False, indent=4)
with open('personagem.json','w') as json_file:
json_file.write(dados_json)

Como podemos observar, os dados agora persistem no arquivo personagem.json

Utilizando uma API

Vamos consumir uma simples API de testes para entendermos melhor a interação com outras aplicações que expõem seus serviços online.

import json
import requests
r = requests.get('https://jsonplaceholder.typicode.com/posts')
posts = r.json()
for post in posts:
print(post) # Imprime todos os posts
print(post['id']) # Imprime todos os ids
print(post['title']) # Imprime todos os títulos
print(post['body']) # Imprime todos os textos

Como podemos observar, conseguimos obter os dados com sucesso e agora podemos trabalhar com eles da forma que desejarmos.

Experimente esta ideia trabalhando com outras API's, por exemplo a do GitHub.

JSONPickle

A biblioteca jsonpickle nos permite serializar e deserializar objetos complexos em Python para JSON e também de JSON.

Para podermos usar suas funcionalidades, precisamos instalar ela com um simples comando:

pip install jsonpickle

Vejamos exemplos dela para ilustrar o seu uso.

Vamos começar criando um objeto Gato:

class Gato:
def __init__(self, nome, raca):
self.nome = nome
self.raca = raca

Agora vamos criar um novo Gato

gato = Gato('Osíris','Sphynx')

Transformando o objeto Gato em uma string JSON e salvando em um arquivo:

import jsonpickle
jsonpickle.set_preferred_backend('json')
jsonpickle.set_encoder_options('json', ensure_ascii=False)
with open('gato.json', 'w') as file:
frozen = jsonpickle.encode(gato)
file.write(frozen)

Nosso objeto agora persiste no arquivo gato.json

Lendo o arquivo JSON e decodificando para recriar o objeto Gato:

with open('gato.json', 'r') as file:
contents = file.read()
unfrozen = jsonpickle.decode(contents)
print(unfrozen) # <__main__.Gato object at 0x7efdfeeca5c0>
print(unfrozen.raca) # Sphynx
print(unfrozen.nome) # Osíris

Essa breve introdução nos mostrou a importância do JSON atualmente e a capacidade que o Python tem de manipulá-lo com uma certa facilidade, inclusive.

Se você deseja obter mais detalhes sobre a biblioteca padrão json em Python, visite docs.python. Bons estudos!