json & Serialização
O módulo json codifica objetos Python em texto JSON e analisa JSON em escalares de dict/list. Personalize com codificadores default e object_hook para viagens de ida e volta - para APIs, prefira Pydantic 2 nas fronteiras.
Receita
import json
from datetime import datetime, timezone
def default(obj):
if isinstance(obj, datetime):
return obj.astimezone(timezone.utc).isoformat()
raise TypeError(type(obj))
payload = json.dumps({"at": datetime.now(timezone.utc)}, default=default)Quando usar isso:
- Arquivos de configuração e saída JSON de CLI
- REST simples sem a sobrecarga do Pydantic
json.loadsem cargas úteis pequenas e confiáveis- Linhas de log NDJSON
- Interoperabilidade com clientes JavaScript
Exemplo de Trabalho
import json
from dataclasses import asdict, dataclass
from datetime import datetime, timezone
from pathlib import Path
@dataclass
class Event:
name: str
at: datetime
def encode_event(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(type(obj))
def save_events(path: Path, events: list[Event]) -> None:
raw = [asdict(e) for e in events]
path.write_text(json.dumps(raw, default=encode_event, indent=2), encoding="utf-8")
def load_events(path: Path) -> list[dict]:
return json.loads(path.read_text(encoding="utf-8"))
events = [Event("login", datetime.now(timezone.utc))]
out = Path("events.json")
save_events(out, events)
print(load_events(out))
out.unlink(missing_ok=True)O que isso demonstra:
- Pipeline Dataclass -> dict -> JSON
defaultpersonalizado para tipos não nativos de JSON- Codificação explícita de arquivo utf-8
- Parse retorna dicionários - valide antes de usar
Mergulho Profundo
Tipos JSON
| Python | JSON |
|---|---|
| dict | object |
| list | array |
| str, int, float, bool, None | scalar |
Desempenho
orjsonPyPI mais rápido para caminhos críticosjson.dumpsbom para CLI e configuração
Armadilhas
- Precisão de float - números JSON são doubles IEEE. Correção: Decimal como str se for dinheiro.
- Tipo de chave apenas str - chaves de dicionário são convertidas para str em JSON. Correção: normalize ao carregar.
- Cargas de arquivos enormes - pico de memória. Correção: streaming
ijsonou delimitado por linha. - Profundidade de entrada não confiável - DoS via objetos aninhados. Correção: limite o tamanho, use um analisador com limites.
- datetime ingênuo em JSON - ambíguo. Correção: sempre UTC ISO com offset.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Pydantic | Validação de modelos de API | Pequenos dumps internos |
| msgpack | IPC binário compacto | Necessidade de legibilidade humana |
| yaml | Configuração humana | API JSON estrita |
FAQs
loads vs load?
loads string; load objeto de arquivo - prefira Path.read_text + loads para clareza.
sort_keys=True?
Diferenças estáveis para configuração - custa sobrecarga de ordenação.
ensure_ascii=False?
Emite caracteres UTF-8 em strings JSON - geralmente desejado em 3.x.
Serialização Decimal?
Converta para str em default - nunca float para dinheiro.
UUID?
str(uuid) no codificador padrão.
Resposta FastAPI?
jsonable_encoder do framework - modelos Pydantic são preferidos.
NDJSON?
Um json.dumps por linha escrito em arquivo ou stdout.
Validação de schema?
jsonschema PyPI ou Pydantic após loads.
pickle vs json?
Nunca use pickle com dados de rede não confiáveis; json para intercâmbio.
indent em produção?
Não - formatar para humanos apenas; compacto em APIs.
Relacionados
- datetime, zoneinfo & time - codificar datetimes
- Pydantic basics - modelos validados
- pathlib & os - caminhos de configuração
- Standard Library Best Practices - regras de serialização
Versões da Pilha: Esta página foi escrita para Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.