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)
  • Booleantrue ou false
  • 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 JSON
  • json.loads() — converte uma string JSON em um objeto Python
  • json.dump() — escreve um objeto Python diretamente em um arquivo JSON
  • json.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:

  • dictObject {}
  • list, tupleArray []
  • strString
  • int, floatNumber
  • Truetrue
  • Falsefalse
  • Nonenull
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=False quando houver caracteres acentuados ou Unicode no conteúdo
  • Defina indent apenas 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.JSONDecodeError ao 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.