W3docs

Python JSON

Aprenda a usar o módulo json do Python para codificar, decodificar, ler e escrever dados JSON, com exemplos práticos e tratamento de erros.

O módulo json embutido do Python permite converter entre objetos Python e texto JSON com apenas duas funções na maioria dos casos. Este capítulo cobre tudo o que você precisa: mapeamento de tipos de dados, dumps/loads para strings, dump/load para arquivos, impressão formatada, tratamento de erros e serialização personalizada.

O que é JSON?

JSON (JavaScript Object Notation) é um formato leve de intercâmbio de dados baseado em texto. É legível por humanos, independente de linguagem e o formato padrão para a maioria das APIs web.

Um documento JSON é construído a partir de duas estruturas:

  • Objects — coleções não ordenadas de pares chave/valor delimitadas por {}. As chaves são sempre strings entre aspas duplas.
  • Arrays — sequências ordenadas de valores delimitadas por [].

Exemplo de documento JSON:

{
  "name": "John Doe",
  "age": 30,
  "city": "New York",
  "hobbies": ["reading", "traveling", "photography"],
  "active": true,
  "score": null
}

Mapeamento de tipos Python–JSON

Ao codificar ou decodificar JSON, o módulo json do Python converte os tipos de acordo com esta tabela:

Tipo PythonTipo JSONTipo Python (após decodificação)
dictobject {}dict
list, tuplearray []list
strstring ""str
int, floatnumberint ou float
True / Falsetrue / falsebool
NonenullNone

Observe que tuplas se tornam arrays JSON e retornam como listas Python após a decodificação.

Codificando objetos Python em strings JSON

json.dumps() (dump-string) serializa um objeto Python em uma string formatada como JSON.

Codificação básica

python— editable, runs on the server

Saída:

{"name": "John Doe", "age": 30, "city": "New York", "hobbies": ["reading", "traveling", "photography"]}

Impressão formatada com indent e sort_keys

Por padrão, json.dumps() produz uma string compacta em uma única linha. Passe indent para produzir saída legível por humanos, e sort_keys=True para ordenar as chaves do dicionário em ordem alfabética:

import json

person = {
    "name": "John Doe",
    "age": 30,
    "city": "New York",
    "hobbies": ["reading", "traveling", "photography"]
}

print(json.dumps(person, indent=2, sort_keys=True))

Saída:

{
  "age": 30,
  "city": "New York",
  "hobbies": [
    "reading",
    "traveling",
    "photography"
  ],
  "name": "John Doe"
}

Use indent=2 ou indent=4 ao escrever arquivos de configuração ou depurar respostas de API — isso facilita a leitura de estruturas aninhadas.

Decodificando strings JSON em objetos Python

json.loads() (load-string) analisa uma string JSON e retorna o objeto Python equivalente.

Decodificação básica

python— editable, runs on the server

Saída:

{'name': 'John Doe', 'age': 30, 'city': 'New York', 'hobbies': ['reading', 'traveling', 'photography']}
<class 'dict'>
John Doe

O valor decodificado é um dicionário Python comum, portanto você pode acessar suas chaves com [] ou .get(), iterá-lo com for, e assim por diante.

Tratando JSON malformado

Se a entrada não for um JSON válido, json.loads() lança json.JSONDecodeError. Sempre capture-o ao trabalhar com dados de fontes externas:

import json

raw = '{"name": "Alice", "age":}'   # invalid — missing value

try:
    data = json.loads(raw)
except json.JSONDecodeError as e:
    print(f"Invalid JSON: {e}")

Saída:

Invalid JSON: Expecting value: line 1 column 24 (char 23)

Consulte o capítulo Python try/except para um guia completo sobre tratamento de exceções.

Trabalhando com JSON aninhado

Objetos JSON podem conter outros objetos e arrays em qualquer profundidade. Acesse valores aninhados usando notação [] encadeada:

python— editable, runs on the server

Saída:

John
traveling

Para estruturas profundamente aninhadas, considere usar .get() com um valor padrão para evitar KeyError em chaves ausentes:

city = person.get("address", {}).get("city", "unknown")

O capítulo de dicionários aninhados cobre padrões para trabalhar com dicionários Python profundamente aninhados.

Lendo e escrevendo arquivos JSON

json.dump() escreve em um objeto de arquivo, e json.load() lê de um. Estes são os equivalentes de arquivo de dumps/loads.

Escrevendo JSON em um arquivo

import json

data = {"name": "Alice", "scores": [95, 87, 92]}

with open("data.json", "w") as f:
    json.dump(data, f, indent=2)

Isso cria data.json com conteúdo formatado. Usar with open(...) garante que o arquivo seja fechado automaticamente — veja tratamento de arquivos em Python para mais detalhes.

Lendo JSON de um arquivo

import json

with open("data.json") as f:
    data = json.load(f)

print(data)
print(data["scores"])

Saída (considerando o arquivo escrito acima):

{'name': 'Alice', 'scores': [95, 87, 92]}
[95, 87, 92]

Exemplo completo de ida e volta

import json

# Write
config = {"host": "localhost", "port": 5432, "debug": False}
with open("config.json", "w") as f:
    json.dump(config, f, indent=2)

# Read back
with open("config.json") as f:
    loaded = json.load(f)

print(loaded["port"])   # 5432
print(type(loaded["port"]))   # <class 'int'>

Obtendo JSON de uma API web

Na maioria dos projetos, você vai decodificar JSON proveniente de uma resposta HTTP. A popular biblioteca requests torna isso simples:

import requests

response = requests.get("https://jsonplaceholder.typicode.com/todos/1")
response.raise_for_status()   # raises an error for 4xx/5xx responses
data = response.json()        # equivalent to json.loads(response.text)

print(data["title"])
print(data["completed"])

response.json() chama json.loads() internamente. Sempre chame raise_for_status() antes de analisar para que uma requisição com falha não retorne silenciosamente um corpo de erro.

Serialização personalizada com default

O módulo json não consegue codificar objetos Python arbitrários (como datetime.date) por padrão. Passe um callable default ou uma subclasse personalizada de JSONEncoder para tratá-los:

import json
import datetime

class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.date):
            return obj.isoformat()
        return super().default(obj)

event = {"name": "Conference", "date": datetime.date(2024, 1, 15)}
print(json.dumps(event, cls=DateEncoder))

Saída:

{"name": "Conference", "date": "2024-01-15"}

O objeto date é convertido para sua string ISO 8601 antes da serialização.

Desserialização personalizada com object_hook

object_hook é chamado para cada object JSON (dict) à medida que é decodificado. Você pode usá-lo para transformar dados durante a execução — por exemplo, convertendo valores string para os tipos Python corretos:

import json

def as_record(d):
    """Convert age field from string to int if present."""
    if "age" in d:
        d["age"] = int(d["age"])
    return d

raw = '{"name": "Bob", "age": "25"}'
person = json.loads(raw, object_hook=as_record)
print(person)
print(type(person["age"]))   # <class 'int'>

Saída:

{'name': 'Bob', 'age': 25}
<class 'int'>

Referência rápida

FunçãoDireçãoFonte/destino
json.dumps(obj)Python → JSONretorna uma str
json.loads(s)JSON → Pythonlê de uma str
json.dump(obj, f)Python → JSONescreve em um arquivo
json.load(f)JSON → Pythonlê de um arquivo

Parâmetros opcionais principais:

  • indent=2 — impressão formatada com recuo de 2 espaços
  • sort_keys=True — ordena as chaves do dicionário em ordem alfabética
  • cls=MyEncoder — usa uma subclasse personalizada de JSONEncoder
  • object_hook=fn — transforma cada object dict decodificado

Prática

Prática
Which Python function converts a Python dictionary to a JSON-formatted string?
Which Python function converts a Python dictionary to a JSON-formatted string?
Was this page helpful?