Processamento de Dados JSON

JSON (JavaScript Object Notation) é o formato de intercâmbio de dados mais comum na web. Quase todas as APIs Web retornam dados JSON. O módulo json do Python torna fácil converter entre objetos Python e strings JSON.


1. Objetos Python <-> Strings JSON

Exemplo: Serializando para String JSON

PYTHON
import json

# Python dict -> string JSON (serialização)
data = {
    "name": "João Silva",
    "age": 25,
    "is_student": False,
    "scores": [85, 92, 78],
    "address": None
}

json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)
▶ Experimente

Saída:

JSON
{
  "name": "João Silva",
  "age": 25,
  "is_student": false,
  "scores": [85, 92, 78],
  "address": null
}
💡 ensure_ascii=False é importante: Sem este parâmetro, caracteres não-ASCII são escapados para códigos Unicode. Use-o para preservar caracteres originais. indent=2 formata a saída para legibilidade. Em produção, use indent=None para comprimir em uma única linha, economizando largura de banda.


2. String JSON -> Objetos Python (Desserialização)

Exemplo: Desserializando uma String JSON

PYTHON
import json

json_str = '{"name": "João Silva", "age": 25, "is_student": false, "scores": [85, 92, 78]}'

data = json.loads(json_str)
print(data)                             # {'name': 'João Silva', 'age': 25, ...}
print(type(data))                       # <class 'dict'>
print(data["name"])                     # João Silva
print(data["scores"][0])                # 85
▶ Experimente

Mapeamento de Tipo JSON para Tipo Python

JSON Python
string str
number int / float
boolean bool
null None
array list
object dict

3. E/S de Arquivo JSON

Exemplo: Lendo e Escrevendo Arquivos JSON

PYTHON
import json

# Escrever em arquivo JSON
data = {
    "students": [
        {"name": "João Silva", "age": 20, "score": 85},
        {"name": "Maria Souza", "age": 21, "score": 92},
        {"name": "Pedro Santos", "age": 19, "score": 78}
    ]
}

with open("alunos.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

# Ler arquivo JSON
with open("alunos.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)

print(f"Número de alunos: {len(loaded['students'])}")
for s in loaded["students"]:
    print(f"  {s['name']}: {s['score']}")
▶ Experimente

Exemplo: Persistência de Dados (Dificuldade ⭐⭐)

PYTHON
import json
import os

DATA_FILE = "notas.json"

def load_notes():
    """Carrega notas do arquivo JSON"""
    if not os.path.exists(DATA_FILE):
        return []
    with open(DATA_FILE, "r", encoding="utf-8") as f:
        return json.load(f)

def save_notes(notes):
    """Salva notas no arquivo JSON"""
    with open(DATA_FILE, "w", encoding="utf-8") as f:
        json.dump(notes, f, ensure_ascii=False, indent=2)

def add_note(titulo, conteudo):
    """Adiciona uma nota"""
    notes = load_notes()
    notes.append({"titulo": titulo, "conteudo": conteudo})
    save_notes(notes)
    print(f"Nota adicionada: {titulo}")

def list_notes():
    """Lista todas as notas"""
    notes = load_notes()
    if not notes:
        print("Nenhuma nota ainda")
        return
    for i, note in enumerate(notes, 1):
        print(f"{i}. {note['titulo']}")

add_note("Aprendendo Python", "Aprendi o módulo JSON hoje")
add_note("Lista de Compras", "Comprar leite, pão, ovos")
list_notes()
▶ Experimente

4. Lidando com Tipos de Dados Complexos

Por padrão, o módulo json só suporta tipos básicos. Objetos personalizados precisam de conversão manual:

Exemplo: Serialização Personalizada

PYTHON
import json
from datetime import datetime

def custom_serializer(obj):
    """Serialização personalizada — lida com tipos como datetime"""
    if isinstance(obj, datetime):
        return obj.strftime("%Y-%m-%d %H:%M:%S")
    raise TypeError(f"Não é possível serializar {type(obj)}")

data = {
    "name": "João Silva",
    "created_at": datetime.now(),
    "active": True
}

json_str = json.dumps(data, default=custom_serializer, ensure_ascii=False, indent=2)
print(json_str)
▶ Experimente

Casos de Uso Comuns


❓ Perguntas Frequentes

P: Qual a diferença entre json.dumps() e json.dump()? R: dumps() retorna uma string JSON (s de string); dump() escreve diretamente em um objeto de arquivo. Similarmente, loads() analisa a partir de uma string; load() lê de um objeto de arquivo. O sufixo 's' indica string. P: Quais as vantagens do JSON sobre CSV? R: JSON suporta estruturas aninhadas (dicts dentro de listas, listas dentro de dicts), enquanto CSV só pode representar tabelas planas. JSON preserva tipos de dados automaticamente (números, booleanos, null), enquanto todos os valores CSV são strings. JSON é mais legível. A desvantagem é que arquivos JSON são geralmente maiores que CSV. P: O que acontece se ensure_ascii=False não for definido? R: Caracteres acentuados (como ç, ã, é) serão escapados para formato \uXXXX. A funcionalidade do programa não é afetada — json.loads() os restaurará automaticamente. No entanto, para legibilidade humana, conteúdo escapado é completamente ilegível. Adicione ensure_ascii=False quando precisar visualizar arquivos JSON manualmente.


📖 Resumo


📝 Atividades

  1. Iniciante (Dificuldade ⭐): Crie um dicionário contendo seu nome, idade e três hobbies (lista). Use json.dumps() para exibir uma string JSON formatada (preserve caracteres, indentação 2).

  2. Intermediário (Dificuldade ⭐⭐): Escreva duas funções: save_contacts(contacts) e load_contacts(). Salve uma lista de contatos (lista de dicts) em contacts.json e carregue automaticamente na inicialização do programa. Cada contato tem nome, telefone e email.

  3. Avançado (Dificuldade ⭐⭐⭐): Implemente um "exportador de dados simples" usando JSON. Dada uma lista de notas de alunos students = [{"name": "João Silva", "scores": {"Português": 85, "Matemática": 92}}], exiba como: 1) Um arquivo JSON formatado; 2) Uma string JSON comprimida (sem indentação); 3) Uma string JSON com chaves ordenadas (sort_keys=True).

100%