JSON (JavaScript Object Notation) é o formato de troca de dados mais utilizado na web moderna. Praticamente toda API REST retorna JSON, arquivos de configuração usam JSON, e bancos de dados NoSQL como MongoDB armazenam dados nesse formato. O Python oferece suporte nativo e extremamente poderoso para JSON através do módulo json, parte da biblioteca padrão.
Neste guia completo, você vai aprender tudo sobre manipulação de dados JSON com Python: desde a serialização básica com json.dumps() e json.loads() até técnicas avançadas como codificadores personalizados, validação com JSON Schema e integração com APIs REST. Vamos começar!
O Que é JSON?
JSON é um formato de texto leve para armazenar e transportar dados estruturados. Ele foi especificado originalmente por Douglas Crockford no JSON.org e posteriormente padronizado pela RFC 7159. Sua sintaxe é simples e legível tanto para humanos quanto para máquinas.
JSON suporta apenas seis tipos de dados:
- String — sequência de caracteres entre aspas duplas
- Number — inteiros ou decimais (ponto flutuante)
- Boolean —
trueoufalse - Null — valor nulo (
null) - Array — lista ordenada de valores entre colchetes
[] - Object — coleção de pares chave/valor entre chaves
{}
{
"nome": "Python",
"versao": 3.12,
"paradigmas": ["Orientado a Objetos", "Funcional", "Imperativo"],
"tipagem": "dinâmica",
"open_source": true,
"criador": null
}
Segundo a MDN Web Docs, JSON é um formato que se destaca por sua simplicidade e ubiquidade na web, sendo suportado nativamente por todas as linguagens de programação modernas.
O Módulo json do Python
O Python inclui o módulo json como parte de sua biblioteca padrão. Isso significa que você não precisa instalar nada — basta importá-lo e começar a usar. A documentação oficial do módulo json é o ponto de partida ideal para consultas aprofundadas.
import json
O módulo oferece quatro funções principais que formam a base de toda manipulação de JSON em Python:
json.dumps()— converte um objeto Python em uma string JSONjson.loads()— converte uma string JSON em um objeto Pythonjson.dump()— escreve um objeto Python diretamente em um arquivo JSONjson.load()— lê um arquivo JSON e o converte em objeto Python
json.dumps() — Serializando Python para JSON
A função json.dumps() (dump string) serializa um objeto Python em uma string JSON. A tabela de conversão segue o mapeamento padrão:
dict→Object{}list,tuple→Array[]str→Stringint,float→NumberTrue→trueFalse→falseNone→null
import json
dados = {
"linguagem": "Python",
"criado_em": 1991,
"tipos": ["int", "float", "str", "list", "dict"],
"interpretada": True,
"autor": None
}
json_string = json.dumps(dados)
print(json_string)
Saída: {"linguagem": "Python", "criado_em": 1991, "tipos": ["int", "float", "str", "list", "dict"], "interpretada": true, "autor": null}
Observe como True se torna true e None se torna null automaticamente, seguindo o padrão JSON.
Parâmetros Avançados do dumps()
O json.dumps() oferece vários parâmetros para controlar a saída:
import json
dados = {"nome": "Python", "versao": 3.12, "features": ["simples", "poderoso"]}
indent — formata com indentação para legibilidade
print(json.dumps(dados, indent=2))
sort_keys — ordena as chaves alfabeticamente
print(json.dumps(dados, indent=2, sort_keys=True))
ensure_ascii — se False, permite caracteres Unicode
print(json.dumps({"nome": "João"}, ensure_ascii=False))
Saída: {"nome": "João"}
separators — personaliza separadores (remove espaços)
print(json.dumps(dados, separators=(",", ":")))
Saída: {"nome":"Python","versao":3.12,"features":["simples","poderoso"]}
O parâmetro ensure_ascii=False é essencial quando você trabalha com textos em português ou outros idiomas com acentos e caracteres especiais, como explica o tutorial da Real Python sobre JSON.
json.loads() — Convertendo JSON para Python
A função json.loads() (load string) faz o caminho inverso: recebe uma string JSON e a converte em um objeto Python.
import json
json_string = '{"nome": "Python", "versao": 3.12, "interpretada": true, "autor": null}'
dados = json.loads(json_string)
print(dados)
Saída: {'nome': 'Python', 'versao': 3.12, 'interpretada': True, 'autor': None}
print(type(dados))
Saída: <class 'dict'>
Perceba que a conversão respeita o mapeamento inverso: true vira True, null vira None, e strings JSON viram strings Python. O resultado é sempre um dicionário Python quando o JSON de origem é um objeto.
json.dump() e json.load() — Trabalhando com Arquivos
As funções json.dump() e json.load() (sem o "s" final) trabalham diretamente com arquivos, evitando a necessidade de strings intermediárias. Este tópico se complementa com o guia de Manipulação de Arquivos TXT, CSV e JSON.
import json
Escrevendo JSON em um arquivo
dados = {
"nome": "Python",
"ano": 1991,
"frameworks": ["Django", "Flask", "FastAPI"]
}
with open("dados.json", "w", encoding="utf-8") as arquivo:
json.dump(dados, arquivo, indent=2, ensure_ascii=False)
Lendo JSON de um arquivo
with open("dados.json", "r", encoding="utf-8") as arquivo:
dados_carregados = json.load(arquivo)
print(dados_carregados["nome"]) # Saída: Python
Sempre use a codificação utf-8 ao trabalhar com arquivos JSON para garantir a compatibilidade com caracteres acentuados e especiais.
Serializando Objetos Python Personalizados
Por padrão, o módulo json não sabe como serializar objetos de classes personalizadas. Tente executar o código abaixo e você receberá um TypeError:
import json
class Pessoa:
def init(self, nome, idade):
self.nome = nome
self.idade = idade
p = Pessoa("Ana", 30)
print(json.dumps(p)) # TypeError: Object of type Pessoa is not JSON serializable
Existem duas abordagens principais para resolver isso.
Método 1: Usando um Custom JSONEncoder
Crie uma subclasse de json.JSONEncoder e sobrescreva o método default(). A documentação oficial do JSONEncoder fornece todos os detalhes desta abordagem.
import json
from datetime import datetime
class Pessoa:
def init(self, nome, idade):
self.nome = nome
self.idade = idade
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Pessoa):
return {"nome": obj.nome, "idade": obj.idade, "_tipo": "Pessoa"}
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
p = Pessoa("Ana", 30)
data = datetime.now()
print(json.dumps({"pessoa": p, "data": data}, cls=CustomEncoder, indent=2))
Método 2: Usando Pydantic
O Pydantic é uma biblioteca que oferece validação de dados e serialização nativa para JSON. É amplamente utilizado com FastAPI e é a abordagem recomendada para projetos profissionais.
from pydantic import BaseModel
class Pessoa(BaseModel):
nome: str
idade: int
p = Pessoa(nome="Ana", idade=30)
print(p.model_dump_json(indent=2))
Saída: {"nome": "Ana", "idade": 30}
O método model_dump_json() do Pydantic já retorna uma string JSON válida, resolvendo a serialização de forma elegante e segura.
Lidando com Erros e Exceções
Ao trabalhar com dados JSON, especialmente aqueles vindos de fontes externas, é fundamental tratar erros de parsing. O módulo json levanta exceções específicas que devem ser capturadas:
import json
def processar_json(texto):
try:
dados = json.loads(texto)
return dados
except json.JSONDecodeError as e:
print(f"Erro ao decodificar JSON: {e}")
print(f"Posição do erro: linha {e.lineno}, coluna {e.colno}")
return None
JSON inválido
json_invalido = '{"nome": "Python", versao: 3.12}'
resultado = processar_json(json_invalido)
Saída: Erro ao decodificar JSON: ...
JSON válido
json_valido = '{"nome": "Python"}'
resultado = processar_json(json_valido)
print(resultado)
Saída: {'nome': 'Python'}
Sempre valide o JSON recebido antes de processá-lo. A combinação de try/except com json.JSONDecodeError garante que sua aplicação não quebre ao receber dados malformados.
Validação com JSON Schema
Para garantir que um JSON siga uma estrutura específica, você pode usar o JSON Schema. Esta especificação define contratos formais para a estrutura de documentos JSON, algo essencial em APIs e integrações entre sistemas.
from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"nome": {"type": "string", "minLength": 1},
"idade": {"type": "integer", "minimum": 0},
"email": {"type": "string", "format": "email"}
},
"required": ["nome", "email"]
}
dados_validos = {"nome": "Ana", "idade": 30, "email": "[email protected]"}
validate(instance=dados_validos, schema=schema) # OK, não levanta exceção
dados_invalidos = {"nome": "", "email": "invalido"}
try:
validate(instance=dados_invalidos, schema=schema)
except ValidationError as e:
print(f"Erro de validação: {e.message}")
Embora a biblioteca jsonschema precise ser instalada separadamente (pip install jsonschema), ela é extremamente útil para validar payloads de API, arquivos de configuração e qualquer dado JSON que precise de uma estrutura previsível.
JSON e APIs REST
JSON é o formato padrão de entrada e saída da maioria das APIs REST modernas. Quando você faz uma requisição HTTP para uma API, a resposta quase sempre vem em JSON. Veja como consumir e enviar JSON usando a biblioteca requests:
import json
import requests
Consumindo uma API que retorna JSON
response = requests.get("https://api.github.com/users/python")
dados = response.json() # Equivalente a json.loads(response.text)
print(f"Repositórios: {dados['public_repos']}")
Enviando JSON para uma API
payload = {"titulo": "Novo Post", "conteudo": "JSON com Python"}
headers = {"Content-Type": "application/json"}
response = requests.post(
"https://jsonplaceholder.typicode.com/posts",
data=json.dumps(payload),
headers=headers
)
print(response.json())
Para dominar completamente o consumo de APIs, confira o guia completo sobre Python Requests para requisições HTTP.
O FastAPI, um dos frameworks web mais populares do Python, usa o Pydantic para validar e serializar JSON automaticamente. A documentação do FastAPI sobre JSON Encoder mostra como o framework lida com tipos personalizados de forma transparente.
Boas Práticas e Performance
Ao trabalhar com JSON em Python, siga estas recomendações:
- Sempre use
ensure_ascii=Falsequando houver caracteres acentuados ou Unicode no conteúdo - Defina
indentapenas em arquivos de configuração — em produção, omita para reduzir o tamanho dos dados trafegados - Use
separators=(",", ":")em APIs para minimizar o payload JSON - Prefira Pydantic ou dataclasses para serialização de objetos em projetos maiores
- Valide dados com JSON Schema quando a estrutura precisar ser garantida
- Trate exceções com
json.JSONDecodeErrorao processar dados de fontes externas
Para projetos que exigem performance máxima, considere alternativas como orjson (escrito em Rust) ou ujson. O módulo nativo json do Python, porém, é suficiente para a grande maioria dos casos de uso e tem a vantagem de não exigir dependências externas.
O tutorial da W3Schools sobre Python JSON oferece exemplos adicionais e exercícios práticos para reforçar o aprendizado.
Conclusão
JSON e Python formam uma combinação poderosa e onipresente no desenvolvimento de software moderno. O módulo json da biblioteca padrão oferece todas as ferramentas necessárias para serializar, desserializar, ler e escrever dados JSON com apenas algumas linhas de código.
Neste guia, você aprendeu:
- Os fundamentos do formato JSON e seus tipos de dados
- As quatro funções principais:
dumps(),loads(),dump(),load() - Como serializar objetos Python personalizados com JSONEncoder e Pydantic
- Como tratar erros de parsing e validar estruturas com JSON Schema
- Como integrar JSON com APIs REST usando a biblioteca requests
- Boas práticas para performance e segurança
Com esse conhecimento, você está preparado para manipular dados JSON em qualquer projeto Python — seja uma aplicação web, um script de automação, uma API REST ou uma pipeline de dados. Para se aprofundar ainda mais, explore a documentação oficial e pratique com dados reais de APIs públicas.