Como manipular JSON com Python: ler, salvar e converter

Cansado de programar?

Conheça a melhor e mais completa formação de Python e Django e sinta-se um programador verdadeiramente competente. Além de Python e Django, você também vai aprender Banco de Dados, SQL, HTML, CSS, Javascript, Bootstrap e muito mais!

Quero aprender Python e Django de Verdade! Quero aprender!
Suporte

Tire suas dúvidas diretamente com o professor

Projetos práticos

Projetos práticos voltados para o mercado de trabalho

Prática profissional

Formação moderna com foco na prática profissional

Download do Artigo

✅ Artigo atualizado em Setembro 2026 (Python 3.x) Nova resposta rápida, tabela load x loads x dump x dumps, acentos e indentação, JSON aninhado, conversão de datetime/set/classes, erros comuns com traceback e 8 exercícios resolvidos. Todos os códigos foram executados.

Resposta rápida

O módulo json (nativo, basta import json) converte dados entre Python e JSON: json.loads() e json.dumps() trabalham com strings, e json.load() e json.dump() com arquivos. Use ensure_ascii=False para manter os acentos e indent=2 para deixar o JSON legível.

1
2
3
4
5
import json
texto = json.dumps({"nome": "João", "ativo": True}, ensure_ascii=False)
print(texto)          # {"nome": "João", "ativo": true}
dados = json.loads(texto)
print(dados["nome"])  # João

Resumo em 30 segundos:

  • O s de loads/dumps é de string; sem o s, load/dump recebem um arquivo aberto.
  • JSON vira dict/list no Python; true, false e null viram True, False e None.
  • JSON exige aspas duplas: aspas simples geram JSONDecodeError.
  • datetime, set e objetos de classes não são serializáveis direto: use o parâmetro default.
  • Ao gravar arquivo com acentos: open(..., "w", encoding="utf-8") + ensure_ascii=False.

Salve salve Pythonista!

JSON (JavaScript Object Notation) é o formato mais usado em APIs e configurações! Biblioteca json é nativa.

Neste guia:

  • ✅ loads/dumps - String ↔ Python
  • ✅ load/dump - Arquivo ↔ Python
  • ✅ Casos práticos - APIs, configs
  • ✅ indent/ensure_ascii - Formatação

O JSON (JavaScript Object Notation) é um formato de dados muito popular na web, que permite a troca de informações estruturadas entre diferentes sistemas.

Ele é amplamente utilizado em aplicações RESTful, em bancos de dados NoSQL, em APIs e em muitos outros contextos.

No Python, a biblioteca padrão json oferece suporte para a manipulação de JSON de forma fácil e eficiente! A referência completa está na documentação oficial do módulo json.

Neste artigo, vamos aprender como manipular JSON com Python. Você vai aprender a escrever dados em um arquivo JSON, ler dados de um arquivo JSON, converter uma string JSON em um objeto Python e também a converter um objeto Python em uma string JSON.

Como um objeto JSON vira um dicionário no Python, vale ter o básico de dicionários no Python e de listas no Python fresco na cabeça.

Então vamos nessa, que temos bastante conteúdo!

Vá Direto ao Assunto…

Escrevendo dados em um arquivo JSON

A primeira competência que vamos aprender é como escrever dados em um arquivo JSON usando Python.

Para isso, precisaremos da biblioteca json e do método dump(). Veja o exemplo abaixo:

1
2
3
4
5
6
7
8
9
10
11
import json

dados = {
    "nome": "João",
    "idade": 30,
    "cidade": "São Paulo"
}

arquivo = open("dados.json", "w")
json.dump(dados, arquivo)
arquivo.close()

No exemplo acima, criamos um dicionário chamado dados, que contém informações pessoais.

O arquivo dados.json será criado e as informações contidas no dicionário serão escritas nesse arquivo.

Note que utilizamos o modo "w" para abrir o arquivo em modo de escrita.

Se você abrir o dados.json em um editor, vai ver tudo em uma linha só e com os acentos escapados:

1
{"nome": "João", "idade": 30, "cidade": "São Paulo"}

Isso não é erro: é o padrão ensure_ascii=True. Na prática, prefira a versão abaixo, com with (que fecha o arquivo sozinho, mesmo se der erro), encoding="utf-8", acentos preservados e indentação:

1
2
3
4
5
6
import json

dados = {"nome": "João", "idade": 30, "cidade": "São Paulo"}

with open("dados.json", "w", encoding="utf-8") as arquivo:
    json.dump(dados, arquivo, ensure_ascii=False, indent=2)

Se quiser entender os modos de abertura ("r", "w", "a") e o with em detalhes, veja o guia de como manipular arquivos em Python.

Lendo dados de um arquivo JSON

Agora que já sabemos como escrever dados em um arquivo JSON, vamos aprender como lê-los de um arquivo para dentro do Python.

Para isso, utilizamos o método load() da biblioteca json. Veja o exemplo a seguir:

1
2
3
4
5
6
7
import json

arquivo = open("dados.json", "r")
dados = json.load(arquivo)
arquivo.close()

print(dados)

Saída:

1
{'nome': 'João', 'idade': 30, 'cidade': 'São Paulo'}

No exemplo acima, abrimos o arquivo dados.json em modo de leitura ("r") e utilizamos o método json.load() para carregar os dados desse arquivo em uma variável chamada dados.

Por fim, exibimos os dados na tela com a função print().

Repare que a saída usa aspas simples: dados já é um dicionário Python, e não mais texto JSON. A forma recomendada de ler, com with e codificação explícita, fica assim:

1
2
3
4
5
6
7
import json

with open("dados.json", encoding="utf-8") as arquivo:
    dados = json.load(arquivo)

print(dados["nome"])  # João
print(type(dados))    # <class 'dict'>

Se o arquivo começar com [, json.load() devolve uma list; se começar com {, devolve um dict.

:bulb: Estou desenvolvendo o Ebookr.ai, uma plataforma que transforma suas ideias em ebooks profissionais usando IA - com geração de capa, infográficos e exportação em PDF. Te convido a conhecer!

Convertendo uma string JSON em um objeto Python

Além de escrever e ler dados de um arquivo JSON, podemos também converter uma string JSON em um objeto Python.

Para isso, utilizamos o método loads() da biblioteca json. Veja o exemplo abaixo:

1
2
3
4
5
6
import json

string_json = '{"nome": "Ana", "idade": 25, "cidade": "Rio de Janeiro"}'
dados = json.loads(string_json)

print(dados)

Saída:

1
{'nome': 'Ana', 'idade': 25, 'cidade': 'Rio de Janeiro'}

No exemplo acima, temos uma string chamada string_json, que contém os mesmos dados do exemplo anterior.

Utilizando o método json.loads(), convertemos essa string em um objeto Python. Em seguida, exibimos os dados na tela.

É exatamente isso que acontece quando você recebe texto JSON de uma API ou de um modelo de linguagem: em um agente de IA em Python, por exemplo, os argumentos que o modelo escolhe para uma ferramenta chegam como string JSON e são convertidos com json.loads() antes de chamar a função.

Convertendo um objeto Python em uma string JSON

Da mesma forma que podemos converter uma string JSON em um objeto Python, também podemos converter um objeto Python em uma string JSON.

Para isso, utilizamos o método dumps() da biblioteca json. Veja o exemplo a seguir:

1
2
3
4
5
6
7
8
9
10
11
import json

dados = {
    "nome": "Pedro",
    "idade": 35,
    "cidade": "Belo Horizonte"
}

string_json = json.dumps(dados)

print(string_json)

Saída:

1
{"nome": "Pedro", "idade": 35, "cidade": "Belo Horizonte"}

No exemplo acima, temos um dicionário chamado dados, que contém as mesmas informações dos exemplos anteriores.

Utilizando o método json.dumps(), convertemos esse dicionário em uma string JSON.

Por fim, exibimos a string na tela com a função print(). Agora as aspas são duplas: string_json é texto (str), pronto para ser enviado a uma API ou gravado em qualquer lugar.

Está curtindo esse conteúdo? :thumbsup:

Que tal receber 30 dias de conteúdo direto na sua Caixa de Entrada?

Sua assinatura não pôde ser validada.
Você fez sua assinatura com sucesso.

Assine as PyDicas e receba 30 dias do melhor conteúdo Python na sua Caixa de Entrada: direto e sem enrolação!

Diferença entre json.load e json.loads (e dump e dumps)

As quatro funções têm nomes quase iguais, e é aí que muita gente se confunde. A regra é uma só: o “s” no final vem de string. Sem o s, a função trabalha com um arquivo aberto.

Função Entrada Saída Quando usar
json.loads(texto) string JSON dict/list Python Texto vindo de API, banco, input(), modelo de IA
json.load(arquivo) arquivo aberto com open() dict/list Python Ler um arquivo .json do disco
json.dumps(obj) objeto Python string JSON Enviar para uma API, logar, guardar em banco
json.dump(obj, arquivo) objeto Python + arquivo aberto em "w" nada (grava no arquivo) Salvar um arquivo .json no disco

Os parâmetros de formatação (indent, ensure_ascii, sort_keys, default) funcionam igual em dump e dumps. Veja as quatro lado a lado em um ciclo completo:

1
2
3
4
5
6
7
8
9
10
11
12
import json

dados = {"curso": "Python", "aulas": 42}

texto = json.dumps(dados)            # dict -> str
print(json.loads(texto) == dados)    # True (str -> dict)

with open("curso.json", "w", encoding="utf-8") as arquivo:
    json.dump(dados, arquivo)        # dict -> arquivo

with open("curso.json", encoding="utf-8") as arquivo:
    print(json.load(arquivo))        # {'curso': 'Python', 'aulas': 42}

Como salvar JSON com acentos e indentado

Por padrão, json.dump() e json.dumps() geram tudo em uma linha e trocam cada caractere acentuado por um código \uXXXX:

1
2
3
import json

print(json.dumps({"nome": "João"}))  # {"nome": "João"}

Para um arquivo legível por humanos, combine três coisas:

  1. encoding="utf-8" no open(), para o arquivo ser gravado em UTF-8 em qualquer sistema operacional (no Windows o padrão pode ser outro);
  2. ensure_ascii=False, para gravar ã em vez de ã;
  3. indent=2 (ou 4), para quebrar linhas e indentar.
1
2
3
4
5
6
7
8
9
import json

produtos = [
    {"nome": "Café", "preco": 12.5, "tags": ["bebida", "orgânico"]},
    {"nome": "Pão de queijo", "preco": 8.0, "tags": []},
]

with open("produtos.json", "w", encoding="utf-8") as arquivo:
    json.dump(produtos, arquivo, ensure_ascii=False, indent=2)

Conteúdo de produtos.json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[
  {
    "nome": "Café",
    "preco": 12.5,
    "tags": [
      "bebida",
      "orgânico"
    ]
  },
  {
    "nome": "Pão de queijo",
    "preco": 8.0,
    "tags": []
  }
]

Dois extras úteis: sort_keys=True ordena as chaves (ótimo para comparar versões de um arquivo) e separators=(",", ":") gera o JSON mais compacto possível, sem espaços:

1
2
3
4
5
6
import json

config = {"debug": False, "versao": "1.0", "autor": "José"}

print(json.dumps(config, ensure_ascii=False, indent=4, sort_keys=True))
print(json.dumps(config, ensure_ascii=False, separators=(",", ":")))

Saída:

1
2
3
4
5
6
{
    "autor": "José",
    "debug": false,
    "versao": "1.0"
}
{"debug":false,"versao":"1.0","autor":"José"}

JSON aninhado: acessar e percorrer

Respostas de API quase sempre trazem objetos dentro de objetos e listas dentro de objetos. Depois do json.loads(), isso vira dicionários dentro de dicionários e listas de dicionários, e você navega encadeando [chave] e [índice]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import json

resposta = '''
{
  "total": 2,
  "usuarios": [
    {"nome": "Ana", "endereco": {"cidade": "Recife"}, "cursos": ["Python", "Django"]},
    {"nome": "Bruno", "cursos": []}
  ]
}
'''

dados = json.loads(resposta)

print(dados["usuarios"][0]["endereco"]["cidade"])

for usuario in dados["usuarios"]:
    cidade = usuario.get("endereco", {}).get("cidade", "não informada")
    qtd = len(usuario["cursos"])
    print(f"{usuario['nome']}: {cidade}, {qtd} curso(s)")

Saída:

1
2
3
Recife
Ana: Recife, 2 curso(s)
Bruno: não informada, 0 curso(s)

Leia o acesso da esquerda para a direita: dados["usuarios"] é uma lista, [0] pega o primeiro usuário (um dicionário), ["endereco"] é outro dicionário e ["cidade"] é a string final.

O truque do laço está no .get("endereco", {}): o Bruno não tem endereço, então em vez de quebrar com KeyError o .get() devolve um dicionário vazio, e o segundo .get() devolve o valor padrão. Use [chave] quando a chave é obrigatória e .get() quando ela pode faltar.

Converter objetos que o JSON não entende (datetime, set, classes)

O JSON só conhece seis tipos, então o módulo json converte assim:

Python JSON Volta como
dict objeto {...} dict (chaves sempre viram str)
list, tuple array [...] list
str string "..." str
int, float number int, float
True, False true, false True, False
None null None

Qualquer outra coisa (datetime, date, set, Decimal, objetos das suas classes) gera TypeError: Object of type ... is not JSON serializable. A solução é o parâmetro default: uma função que o dumps() chama para cada objeto que ele não sabe converter, e que deve devolver algo serializável.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import json
from datetime import datetime, date

pedido = {
    "id": 42,
    "criado_em": datetime(2026, 9, 26, 14, 30),
    "tags": {"urgente"},
}

def converter(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    if isinstance(obj, set):
        return sorted(obj)
    raise TypeError(f"Tipo {type(obj).__name__} não é serializável")

print(json.dumps(pedido, default=converter))

Saída:

1
{"id": 42, "criado_em": "2026-09-26T14:30:00", "tags": ["urgente"]}

O caminho de volta é manual: o JSON guarda só o texto, então você reconverte o campo depois do loads():

1
2
3
4
5
6
7
8
import json
from datetime import datetime

texto = '{"id": 42, "criado_em": "2026-09-26T14:30:00"}'
dados = json.loads(texto)
dados["criado_em"] = datetime.fromisoformat(dados["criado_em"])

print(dados["criado_em"].year)  # 2026

Para objetos das suas próprias classes, o jeito mais simples é usar uma dataclass e converter com asdict() na ida e com ** na volta:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import json
from dataclasses import dataclass, asdict

@dataclass
class Aluno:
    nome: str
    nota: float

aluno = Aluno("Carla", 9.5)
print(json.dumps(asdict(aluno)))   # {"nome": "Carla", "nota": 9.5}

texto = '{"nome": "Diego", "nota": 7.0}'
outro = Aluno(**json.loads(texto))
print(outro)                       # Aluno(nome='Diego', nota=7.0)

Esses casos práticos de JSON aparecem o tempo todo em integrações reais - é esse tipo de projeto, do básico ao avançado, que você constrói na Jornada Python:

Casos Práticos

1. Trabalhar com APIs

1
2
3
4
5
6
7
8
9
10
11
import json
import requests

# Fazer requisição
response = requests.get('https://api.example.com/users')

# Parse JSON
users = response.json()  # Ou: json.loads(response.text)

for user in users:
    print(f"{user['name']} - {user['email']}")

O .json() da linha 8 é um método do objeto de resposta da biblioteca requests (instalada com pip install requests), e não do módulo json: ele só faz o json.loads() do corpo da resposta por você. A URL acima é um exemplo; troque por uma API real para testar.

2. Arquivo de Configuração

1
2
3
4
5
6
7
8
9
10
11
12
13
import json

# Ler config
with open('config.json', 'r') as f:
    config = json.load(f)

print(config['database']['host'])
print(config['api_key'])

# Atualizar e salvar
config['debug'] = False
with open('config.json', 'w') as f:
    json.dump(config, f, indent=2)

3. JSON Nested (Aninhado)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import json

data = {
    'usuario': {
        'nome': 'Alice',
        'endereco': {
            'rua': 'Rua A',
            'cidade': 'São Paulo'
        }
    }
}

print(data['usuario']['endereco']['cidade'])  # São Paulo

# Serializar com indentação
json_str = json.dumps(data, indent=2, ensure_ascii=False)
print(json_str)

4. Validação de JSON

1
2
3
4
5
6
7
8
9
import json

json_string = '{"nome": "Bob", "idade": 25}'

try:
    dados = json.loads(json_string)
    print("JSON válido!")
except json.JSONDecodeError as e:
    print(f"JSON inválido: {e}")

Saída: JSON válido!. Se a string tiver um erro de sintaxe, como '{"nome": "Bob",}', o except captura e mostra JSON inválido: Expecting property name enclosed in double quotes: line 1 column 16 (char 15). O JSONDecodeError é uma subclasse de ValueError; veja mais sobre try/except no post de tratamento de erros e exceções no Python.

json vs dict

JSON é apenas uma string formatada. Dict é um objeto Python.

1
2
3
4
5
6
7
8
9
10
11
import json

# Dict Python
dict_py = {'nome': 'Alice', 'idade': 25}

# JSON (string)
json_str = '{"nome": "Alice", "idade": 25}'

# Conversão
json_from_dict = json.dumps(dict_py)  # dict → JSON
dict_from_json = json.loads(json_str)  # JSON → dict

As diferenças que mais pegam na hora de escrever JSON “na mão”:

  Dict Python JSON
O que é objeto na memória texto (str ou arquivo)
Aspas simples ou duplas só duplas
Booleanos e nulo True, False, None true, false, null
Chaves qualquer tipo imutável (1, "a", tupla) só strings
Vírgula depois do último item permitida proibida
Comentários # no código não existem

Erros comuns

1. json.decoder.JSONDecodeError: aspas simples ou vírgula sobrando

1
2
3
import json

dados = json.loads("{'nome': 'Ana'}")
1
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

A mesma mensagem aparece com uma vírgula depois do último item, como em '{"nome": "Ana", "idade": 25,}' (line 1 column 29 (char 28)). O texto de um dict Python impresso com print() não é JSON válido: use aspas duplas, remova a vírgula final e, se o texto veio de str(dicionario), gere-o com json.dumps(dicionario). A posição indicada em char aponta onde o parser parou.

2. TypeError: Object of type datetime is not JSON serializable

1
2
3
4
import json
from datetime import datetime

json.dumps({"criado_em": datetime.now()})
1
TypeError: Object of type datetime is not JSON serializable

O JSON não tem tipo de data. Converta antes (datetime.now().isoformat()) ou passe default= para o dumps(), como na seção Converter objetos que o JSON não entende. O mesmo erro aparece com set (Object of type set is not JSON serializable): converta para list.

3. Acentos virando é ou é

1
2
3
4
5
6
7
import json

with open("acentos.json", "w", encoding="utf-8") as f:
    json.dump({"nome": "José", "cidade": "São Paulo"}, f, ensure_ascii=False)

with open("acentos.json", encoding="cp1252") as f:  # codificação errada
    print(json.load(f))
1
{'nome': 'José', 'cidade': 'São Paulo'}

é no lugar de é significa que um arquivo UTF-8 foi lido com outra codificação, o que acontece no Windows quando você não informa encoding no open(). A correção é passar encoding="utf-8" na escrita e na leitura. Já o é não é bug: é o escape padrão do ensure_ascii=True, e o json.load() o converte de volta para é. Se quer ver o acento no arquivo, use ensure_ascii=False.

4. Confundir load com loads

1
2
3
import json

dados = json.load('{"nome": "Ana"}')
1
AttributeError: 'str' object has no attribute 'read'

json.load() espera um arquivo (ele chama .read() no que recebe). Para string, use json.loads(). O erro inverso, passar o arquivo para json.loads(arquivo), termina com TypeError: the JSON object must be str, bytes or bytearray, not TextIOWrapper.

5. KeyError em JSON aninhado

1
2
3
4
import json

dados = json.loads('{"usuario": {"nome": "Bruno"}}')
print(dados["usuario"]["endereco"]["cidade"])
1
KeyError: 'endereco'

A chave não existe naquele nível. Confira a estrutura com print(json.dumps(dados, indent=2)) e, se o campo for opcional, use .get() com valor padrão: dados["usuario"].get("endereco", {}).get("cidade", "não informada") resulta em 'não informada'.

Exercícios resolvidos

Quer praticar isso em projetos guiados, consumindo APIs e salvando dados de verdade? Esse é o tipo de exercício que aparece ao longo do nosso curso de Python completo. Antes, tente resolver os exercícios abaixo sem olhar a solução.

Exercício 1. Converta o dicionário {"titulo": "Cidade de Deus", "ano": 2002, "nacional": True} em uma string JSON mantendo os acentos, imprima a string e o tipo dela.

Ver solução
1
2
3
4
5
6
7
import json

filme = {"titulo": "Cidade de Deus", "ano": 2002, "nacional": True}
texto = json.dumps(filme, ensure_ascii=False)

print(texto)
print(type(texto))

Saída: {"titulo": "Cidade de Deus", "ano": 2002, "nacional": true} e <class 'str'>

dumps() devolve uma str, e o True do Python vira true no JSON.

Exercício 2. Dada a string '{"aluno": "Lia", "notas": [7.5, 8, 9.5]}', calcule a média das notas e imprima Lia: 8.33.

Ver solução
1
2
3
4
5
6
7
import json

texto = '{"aluno": "Lia", "notas": [7.5, 8, 9.5]}'
dados = json.loads(texto)

media = sum(dados["notas"]) / len(dados["notas"])
print(f"{dados['aluno']}: {media:.2f}")

Saída: Lia: 8.33

Depois do loads(), dados["notas"] é uma lista Python comum, então sum() e len() funcionam direto.

Exercício 3. (Estilo prova) Complete a frase: “A leitura de um arquivo JSON deve ser feita com o método __. O único parâmetro obrigatório para carregar os dados é o __, que deve ser um objeto de arquivo aberto.”

  • a) json.loads() / s, a string com o conteúdo
  • b) json.load() / fp, o objeto de arquivo
  • c) json.read() / path, o caminho do arquivo
  • d) json.open() / filename, o nome do arquivo
Ver solução
1
2
3
4
5
6
import json

with open("dados.json", encoding="utf-8") as fp:
    dados = json.load(fp)

print(dados["nome"])

Saída: João (com o dados.json criado no início do post)

Resposta: b. A assinatura é json.load(fp, ...); todos os outros parâmetros são opcionais. loads() recebe string (não arquivo), e json.read() e json.open() não existem.

Exercício 4. (Estilo prova) Qual é a saída de print(json.dumps({"ok": True, "valor": None}))?

  • a) {"ok": True, "valor": None}
  • b) {"ok": true, "valor": null}
  • c) {'ok': true, 'valor': null}
  • d) TypeError: Object of type NoneType is not JSON serializable
Ver solução
1
2
3
import json

print(json.dumps({"ok": True, "valor": None}))

Saída: {"ok": true, "valor": null}

Resposta: b. No JSON, True vira true e None vira null, sempre com aspas duplas nas chaves. None é serializável, então não há erro.

Exercício 5. Salve a lista ["Estudar funções", "Revisar dicionários", "Praticar JSON"] em tarefas.json com acentos legíveis e indentação. Depois leia o arquivo e imprima quantas tarefas existem e qual é a primeira.

Ver solução
1
2
3
4
5
6
7
8
9
10
11
import json

tarefas = ["Estudar funções", "Revisar dicionários", "Praticar JSON"]

with open("tarefas.json", "w", encoding="utf-8") as arquivo:
    json.dump(tarefas, arquivo, ensure_ascii=False, indent=2)

with open("tarefas.json", encoding="utf-8") as arquivo:
    lidas = json.load(arquivo)

print(len(lidas), lidas[0])

Saída: 3 Estudar funções

O JSON não precisa começar com um objeto: uma lista também é JSON válido, e volta do load() como list.

Exercício 6. A string abaixo tem pedidos com itens aninhados. Imprima o total de cada pedido (quantidade vezes preço, somado).

1
2
3
4
5
6
7
texto = '''
{"pedidos": [
  {"id": 1, "itens": [{"produto": "Caneta", "qtd": 3, "preco": 2.5}]},
  {"id": 2, "itens": [{"produto": "Caderno", "qtd": 1, "preco": 20.0},
                      {"produto": "Lápis", "qtd": 4, "preco": 1.25}]}
]}
'''
Ver solução
1
2
3
4
5
6
7
import json

dados = json.loads(texto)

for pedido in dados["pedidos"]:
    total = sum(item["qtd"] * item["preco"] for item in pedido["itens"])
    print(f"Pedido {pedido['id']}: R$ {total:.2f}")

Saída:

1
2
Pedido 1: R$ 7.50
Pedido 2: R$ 25.00

Um laço percorre a lista de pedidos e, para cada um, uma generator expression percorre a lista interna de itens.

Exercício 7. Serialize {"nome": "Hackathon da turma", "data": date(2026, 10, 17)} para JSON usando o parâmetro default com uma lambda.

Ver solução
1
2
3
4
5
6
7
import json
from datetime import date

evento = {"nome": "Hackathon da turma", "data": date(2026, 10, 17)}

texto = json.dumps(evento, default=lambda obj: obj.isoformat())
print(texto)

Saída: {"nome": "Hackathon da turma", "data": "2026-10-17"}

O dumps() só chama o default para o objeto date, que ele não sabe converter; str já é serializável e passa direto.

Exercício 8. (Estilo prova) O que o código abaixo imprime?

1
2
3
4
5
6
7
import json

original = {1: "um", 2: "dois"}
copia = json.loads(json.dumps(original))

print(copia)
print(copia == original)
  • a) {1: 'um', 2: 'dois'} e True
  • b) {'1': 'um', '2': 'dois'} e False
  • c) {'1': 'um', '2': 'dois'} e True
  • d) TypeError, porque chaves int não são permitidas
Ver solução

Saída:

1
2
{'1': 'um', '2': 'dois'}
False

Resposta: b. Chaves de objeto JSON são sempre strings, então o dumps() converte 1 em "1" sem erro, e o loads() devolve '1'. Como 1 != '1', os dicionários são diferentes. O mesmo tipo de perda acontece com tuplas, que voltam como listas.

Conclusão

Neste guia da biblioteca json, você aprendeu:

✅ loads() - String JSON → Python
✅ dumps() - Python → String JSON
✅ load()/dump() - Arquivos
✅ indent - Formatar saída
✅ Casos práticos - APIs, configs, validação

Principais lições:

  • JSON é string, dict é objeto
  • loads/dumps para strings
  • load/dump para arquivos
  • indent=2 deixa JSON legível
  • ensure_ascii=False preserva acentos
  • default= resolve datetime, set e classes

Próximos passos:

Neste artigo, aprendemos como manipular JSON com Python!

Com a biblioteca json, podemos realizar essas tarefas de forma simples e eficiente.

Com o tempo e a prática, você se tornará um especialista em manipulação de JSON com Python!

Perguntas frequentes

Como usar JSON em Python?

Importe o módulo nativo com import json (não precisa instalar nada). Use json.loads(texto) para transformar uma string JSON em dicionário ou lista, json.dumps(obj) para gerar a string JSON a partir de um objeto Python, json.load(arquivo) para ler um arquivo .json aberto com open() e json.dump(obj, arquivo) para gravar nele.

Qual a diferença entre json.load e json.loads?

json.load() lê de um arquivo aberto (qualquer objeto com método read()), enquanto json.loads() lê de uma string; o s no final vem de string. O mesmo vale para a escrita: json.dump(obj, arquivo) grava em arquivo e json.dumps(obj) devolve uma string. Passar uma string para json.load() gera AttributeError: 'str' object has no attribute 'read'.

Como ler um arquivo JSON em Python?

Abra o arquivo com with open('dados.json', encoding='utf-8') as arquivo: e chame dados = json.load(arquivo). O resultado é um objeto Python comum: um dict se o JSON começar com chaves e uma list se começar com colchetes. O with fecha o arquivo automaticamente.

Como salvar JSON com acentos e indentado em Python?

Use json.dump(dados, arquivo, ensure_ascii=False, indent=2) com o arquivo aberto em open('dados.json', 'w', encoding='utf-8'). Sem ensure_ascii=False, o Python grava os acentos escapados, como Jo\u00e3o; sem encoding='utf-8', o arquivo pode ser salvo em outra codificação no Windows e os acentos aparecem quebrados ao abrir.

Como resolver o erro Object of type datetime is not JSON serializable?

O JSON só entende dict, list, str, int, float, bool e None. Para outros tipos, passe uma função no parâmetro default, que o json.dumps() chama para cada objeto que ele não sabe converter. Exemplo: json.dumps(dados, default=lambda obj: obj.isoformat()) transforma um datetime em texto no formato ISO, como 2026-09-26T14:30:00.

Qual a diferença entre JSON e dicionário Python?

JSON é um formato de texto (uma string) usado para trocar dados entre sistemas; dicionário é um objeto Python na memória. Eles se parecem, mas o JSON exige aspas duplas e escreve true, false e null, enquanto o Python usa True, False e None. json.loads() converte o texto em dicionário e json.dumps() faz o caminho inverso.

A leitura de um arquivo JSON deve ser feita com qual método e qual é o parâmetro obrigatório?

Com o método json.load(). O único parâmetro obrigatório é o fp, o objeto de arquivo já aberto (por exemplo, o retornado por open('dados.json')), que deve ter o método read(). Os demais parâmetros, como object_hook e parse_float, são opcionais.

O que é o .json() que aparece em códigos Python com requests?

É um método do objeto de resposta da biblioteca requests, não do módulo json. resposta.json() pega o corpo da resposta HTTP e faz o mesmo que json.loads(resposta.text), devolvendo um dicionário ou lista. Se o corpo não for um JSON válido, ele levanta um erro de decodificação.

Começe agora sua Jornada na Programação!

Não deixe para amanhã o sucesso que você pode começar a construir hoje!

#newsletter Olá :wave: Curtiu o artigo? Então faça parte da nossa Newsletter! Privacidade Não se preocupe, respeitamos sua privacidade. Você pode se descadastrar a qualquer momento.