JSON e Python falam os mesmos formatos
JSON é o formato padrão para APIs, arquivos de config e troca de dados na web. Felizmente para programadores Python, um objeto JSON mapeia diretamente para um dict Python, um array JSON para uma list, uma string JSON para uma str. Esse alinhamento próximo é por que ler e escrever JSON em Python é uma operação de duas linhas.
O módulo json da biblioteca padrão cuida das duas direções.
Parsando uma string JSON
json.loads(text) — "load string" — recebe uma string em formato JSON e retorna o objeto Python que ela representa:
O resultado é um dict comum. Você acessa as chaves como qualquer dict — sem wrapper especial de JSON, sem método .parse() no resultado.
Se a string não for JSON válido, json.loads lança json.JSONDecodeError. A mensagem de erro inclui a linha e coluna do problema, o que geralmente basta para identificar uma vírgula faltando ou uma aspa não escapada.
Escrevendo JSON como string
json.dumps(data) — "dump string" — faz o oposto: recebe um objeto Python e retorna uma string JSON:
True, False e None do Python são traduzidos para true, false e null do JSON automaticamente. Números e strings passam sem mudança. Listas viram arrays, dicts viram objects.
Pretty printing
A saída padrão de json.dumps é compacta — bom para transporte em rede, difícil para humanos. Passe indent=2 para algo mais legível:
Algumas outras opções de dumps que vale conhecer:
sort_keys=True— ordena chaves de objeto alfabeticamente. Útil para saída determinística (arquivos de config, fixtures de teste, diffs).ensure_ascii=False— escreve caracteres não-ASCII (é, ü, 中) como eles mesmos em vez de escapes\u. Geralmente a escolha certa para arquivos UTF-8.separators=(",", ":")— saída mais compacta possível. Combinado comensure_ascii=False, dá o JSON UTF-8 mais compacto que você consegue produzir.
Lendo JSON de um arquivo
json.load(file) — sem s — lê direto de um objeto de arquivo. O padrão comum junta com with open:
import json
with open("config.json") as f:
config = json.load(f)
print(config["version"])
Sem precisar ler o arquivo inteiro para uma string primeiro; json.load faz streaming pelo objeto de arquivo.
Escrevendo JSON em um arquivo
json.dump(data, file) é o contraponto para escrita de arquivo:
import json
data = {"created": "2026-01-01", "items": [1, 2, 3]}
with open("state.json", "w") as f:
json.dump(data, f, indent=2)
A opção indent funciona aqui também. Abra o arquivo resultante e você vai ver um documento JSON bem formatado.
Lendo uma resposta de API JSON
A maioria das bibliotecas HTTP te dá bytes ou texto; você chama json.loads para transformar em dados utilizáveis:
import json
import urllib.request
with urllib.request.urlopen("https://api.example.com/users/1") as response:
text = response.read().decode("utf-8")
user = json.loads(text)
print(user["name"])
A biblioteca requests (coberta separadamente) pula um passo — tem um método .json() na resposta que chama json.loads para você.
O que JSON pode e não pode representar
O sistema de tipos do JSON é mais estreito do que o do Python. O mapeamento nas duas direções:
| Python | JSON |
|---|---|
dict | object |
list, tuple | array |
str | string |
int, float | number |
True | true |
False | false |
None | null |
Tuplas voltam como listas — a "tupla-idade" se perde. Sets, classes customizadas e objetos datetime não podem ser serializados por padrão; você recebe TypeError: Object of type X is not JSON serializable.
Lidando com datetime e objetos customizados
Duas abordagens comuns.
Converta para uma estrutura segura para JSON primeiro. Faça a transformação no seu próprio código, depois serialize um dict simples:
Passe uma função default=. json.dumps chama para cada valor que não sabe serializar:
Ao ler os dados de volta, você precisa converter essas strings ISO para datetime você mesmo — o JSON não lembra o que eram originalmente.
Round trip de um dict por JSON
Uma checagem rápida de sanidade que dicts sobrevivem:
Os valores são iguais, mas são objetos diferentes. Isso muitas vezes é o que você quer — json.dumps + json.loads é uma forma barata de fazer uma cópia profunda de qualquer estrutura compatível com JSON.
Um exemplo realista
Um script pequeno que carrega uma config JSON, atualiza um campo e salva de volta:
import json
from pathlib import Path
config_path = Path("settings.json")
# Load (with a default if the file doesn't exist).
if config_path.exists():
config = json.loads(config_path.read_text())
else:
config = {"theme": "dark", "last_opened": None}
# Update.
config["last_opened"] = "2026-01-15"
# Save, pretty-printed.
config_path.write_text(json.dumps(config, indent=2, ensure_ascii=False))
Esse é um ciclo completo "ler, modificar, escrever" JSON em uma dúzia de linhas.
Alguns hábitos
- Use
with open(...)para arquivos, sempre. JSON é só texto; todas as regras de manipulação de arquivo se aplicam. - Prefira
indent=2para arquivos que humanos leem — config, fixtures, dados exportados. Pule para tráfego de rede onde compactação importa. - Defina
ensure_ascii=Falsepara saída UTF-8 para que nomes com acentos ou caracteres não latinos fiquem legíveis. - Valide com
try/except json.JSONDecodeErrorao parsear dados que você não produziu.
Na sequência
JSON lida com dados chave-valor. A próxima ferramenta no mesmo capítulo é CSV — o suporte embutido do Python para o formato tabular por trás da maioria das exportações de planilha que você vai encontrar.
Perguntas frequentes
Como parseio JSON em Python?
Use json.loads(text) para uma string JSON ou json.load(file) para um objeto de arquivo. Os dois retornam um dict Python (ou list, dependendo do JSON). Exemplo: data = json.loads('{"name": "Rosa"}') — data['name'] é 'Rosa'.
Como converto um dicionário Python para JSON?
json.dumps(meu_dict) retorna uma string JSON. json.dump(meu_dict, file) escreve direto num objeto de arquivo. Passe indent=2 para saída pretty-printed: json.dumps(data, indent=2).
Qual a diferença entre json.loads e json.load?
loads (com o s) recebe uma string. load (sem s) recebe um objeto de arquivo. Idem para dumps vs dump. O s é de string; é o jeito mais fácil de lembrar qual é qual.
Como lido com datas e objetos customizados em JSON?
JSON não tem tipo de data, então passe datas como strings ISO-8601 e parseie de volta manualmente. Para classes customizadas, ou forneça uma função default= para json.dumps que retorna uma representação segura para JSON, ou converta para dict você mesmo antes de serializar.