Converter CSV para JSON em Python — Guia json.dumps()

·Backend Developer·Revisado porPriya Sharma·Publicado

Use o CSV to JSON gratuito diretamente no seu navegador — sem instalação.

Experimentar CSV to JSON online →

Arquivos CSV aparecem em todo lugar — relatórios exportados, dumps de banco de dados, extrações de log — e cedo ou tarde você precisará converter esse CSV para JSON em Python. A biblioteca padrão cuida disso com dois módulos: csv.DictReader transforma cada linha em um dict Python, e json.dumps() serializa esses dicts para uma string JSON. Para uma conversão rápida sem código, o conversor CSV para JSON faz isso instantaneamente no navegador. Este guia cobre o caminho programático completo: json.dump() vs json.dumps(), gravação de JSON em arquivos, serialização de dataclasses, conversão de tipos para valores CSV, tratamento de datetime e Decimal, e alternativas de alta performance como orjson. Todos os exemplos são para Python 3.10+.

  • csv.DictReader produz uma lista de dicts — serialize a lista completa com json.dump(rows, f, indent=2) para gravar um arquivo JSON.
  • json.dump() grava diretamente em um objeto arquivo. json.dumps() retorna uma string. Escolha o correto e evite uma cópia desnecessária.
  • Valores CSV são sempre strings. Converta colunas numéricas explicitamente (int(), float()) antes de serializar para JSON.
  • Passe ensure_ascii=False para json.dumps() para preservar caracteres Unicode — nomes acentuados, texto CJK — na saída.
  • Para datetime, UUID ou Decimal vindos do CSV, use o parâmetro default= com uma função de fallback personalizada.
Before · json
After · json
order_id,product,quantity,price
ORD-7291,Wireless Keyboard,2,49.99
ORD-7292,USB-C Hub,1,34.50
[
  {
    "order_id": "ORD-7291",
    "product": "Wireless Keyboard",
    "quantity": "2",
    "price": "49.99"
  },
  {
    "order_id": "ORD-7292",
    "product": "USB-C Hub",
    "quantity": "1",
    "price": "34.50"
  }
]
Nota:Observe que quantity e price aparecem como strings JSON ("2", "49.99") na saída bruta. CSV não tem sistema de tipos — todo valor é uma string. A correção disso é abordada na seção de conversão de tipos abaixo.

json.dumps() — Serializar um Dict Python para String JSON

O módulo json vem com toda instalação Python — sem pip install necessário. json.dumps(obj) recebe um objeto Python (dict, list, string, número, bool ou None) e retorna uma str contendo JSON válido. Um dicionário Python parece similar a um objeto JSON, mas são fundamentalmente diferentes: um dict é uma estrutura de dados Python na memória, e uma string JSON é texto serializado. Chamar json.dumps() faz essa ponte.

Exemplo Mínimo — Uma Linha CSV para JSON

Python 3.10+
import json

# Uma única linha CSV representada como dict Python
server_entry = {
    "hostname": "web-prod-03",
    "ip_address": "10.0.12.47",
    "port": 8080,
    "region": "eu-west-1"
}

# Converter dict para string JSON
json_string = json.dumps(server_entry)
print(json_string)
# {"hostname": "web-prod-03", "ip_address": "10.0.12.47", "port": 8080, "region": "eu-west-1"}
print(type(json_string))
# <class 'str'>

Isso produz JSON compacto em uma linha — bom para payloads e armazenamento, terrível para leitura. Adicione indent=2 para obter saída legível:

Python 3.10+ — saída formatada
import json

server_entry = {
    "hostname": "web-prod-03",
    "ip_address": "10.0.12.47",
    "port": 8080,
    "region": "eu-west-1"
}

pretty_json = json.dumps(server_entry, indent=2)
print(pretty_json)
# {
#   "hostname": "web-prod-03",
#   "ip_address": "10.0.12.47",
#   "port": 8080,
#   "region": "eu-west-1"
# }

Mais dois parâmetros que uso em quase todas as chamadas: sort_keys=True ordena as chaves do dicionário alfabeticamente (ótimo para comparar arquivos JSON entre versões), e ensure_ascii=False preserva caracteres não-ASCII em vez de escapá-los para sequências \uXXXX.

Python 3.10+ — sort_keys e ensure_ascii
import json

warehouse_record = {
    "sku": "WH-9031",
    "location": "Armazém Lisboa 3",
    "quantity": 240,
    "last_audit": "2026-03-10"
}

output = json.dumps(warehouse_record, indent=2, sort_keys=True, ensure_ascii=False)
print(output)
# {
#   "last_audit": "2026-03-10",
#   "location": "Armazém Lisboa 3",
#   "quantity": 240,
#   "sku": "WH-9031"
# }

Uma observação rápida sobre o parâmetro separators: o padrão é (", ", ": ") que adiciona espaços após vírgulas e dois-pontos. Para a saída mais compacta possível (útil ao incorporar JSON em parâmetros de URL ou reduzir bytes em respostas de API), passe separators=(",", ":").

Nota:Um dict Python e um objeto JSON parecem quase idênticos quando impressos. A diferença: json.dumps() converte True do Python para true do JSON, None para null, e envolve strings em aspas duplas (Python permite aspas simples, JSON não). Use sempre json.dumps() para produzir JSON válido — não confie em str() ou repr().

csv.DictReader para Arquivo JSON — O Pipeline Completo

A tarefa mais comum no mundo real é ler um arquivo CSV inteiro e salvá-lo como JSON. Aqui está o script completo em menos de 10 linhas. csv.DictReader produz um iterador de objetos dict — um por linha, usando a primeira linha como chaves. Envolvê-lo com list() coleta todas as linhas em uma lista Python, que serializa para um array JSON.

Python 3.10+ — conversão completa de CSV para JSON
import csv
import json

# Passo 1: Ler linhas do CSV em uma lista de dicts
with open("inventory.csv", "r", encoding="utf-8") as csv_file:
    rows = list(csv.DictReader(csv_file))

# Passo 2: Gravar a lista como arquivo JSON
with open("inventory.json", "w", encoding="utf-8") as json_file:
    json.dump(rows, json_file, indent=2, ensure_ascii=False)

print(f"Convertidas {len(rows)} linhas para inventory.json")

Duas chamadas open(): uma para ler o CSV, outra para gravar o JSON. Esse é o padrão completo. Observe que aqui usamos json.dump() (sem o s) — ele grava diretamente no identificador de arquivo. Usar json.dumps() retornaria uma string que você precisaria gravar separadamente com f.write(). json.dump() é mais eficiente em memória porque transmite a saída em vez de construir a string inteira na memória antes.

Quando você precisa do JSON como string em vez de arquivo — para incorporar em um payload de API, imprimir no stdout ou inserir em uma coluna de banco de dados — use json.dumps():

Python 3.10+ — linhas CSV como string JSON
import csv
import json

with open("sensors.csv", "r", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))

# Obter o JSON como string em vez de gravar em arquivo
json_payload = json.dumps(rows, indent=2)
print(json_payload)
# [
#   {
#     "sensor_id": "TMP-4401",
#     "location": "Edifício 7 - Andar 2",
#     "reading": "22.4",
#     "unit": "celsius"
#   },
#   ...
# ]

Uma linha vs. conjunto completo: ao chamar json.dumps(single_dict) você obtém um objeto JSON ({...}). Ao chamar json.dumps(list_of_dicts) você obtém um array JSON ([{...}, {...}]). A forma do container externo depende do que você passa. A maioria dos consumidores espera um array para dados tabulares.

Tratando Valores Não-String — Conversão de Tipos do CSV

Aqui está o detalhe que pega todo mundo na primeira vez: csv.DictReader retorna todo valor como string. O número 42 no seu CSV vira a string "42" no dict. Se você serializar isso diretamente com json.dumps(), seu JSON terá "quantity": "42" em vez de "quantity": 42. APIs que validam tipos vão rejeitar isso. É preciso converter os valores explicitamente.

Python 3.10+ — conversão de tipos para linhas CSV
import csv
import json

def coerce_types(row: dict) -> dict:
    """Converter valores string para tipos Python apropriados."""
    return {
        "sensor_id": row["sensor_id"],
        "location": row["location"],
        "temperature": float(row["temperature"]),
        "humidity": float(row["humidity"]),
        "battery_pct": int(row["battery_pct"]),
        "active": row["active"].lower() == "true",
    }

with open("sensor_readings.csv", "r", encoding="utf-8") as f:
    rows = [coerce_types(row) for row in csv.DictReader(f)]

print(json.dumps(rows[0], indent=2))
# {
#   "sensor_id": "TMP-4401",
#   "location": "Edifício 7 - Andar 2",
#   "temperature": 22.4,
#   "humidity": 58.3,
#   "battery_pct": 87,
#   "active": true
# }

Agora temperature é um float, battery_pct é um inteiro, e active é um booleano na saída JSON. A função de conversão é específica para o seu esquema CSV — não há uma forma genérica de inferir tipos a partir de dados CSV, então escrevo uma função por formato de CSV.

Serializando Objetos Personalizados e Tipos Não-Padrão

O módulo json do Python não consegue serializar datetime, UUID, Decimal, ou classes personalizadas por padrão. Chamar json.dumps() em qualquer um deles lança um TypeError. Há duas abordagens para lidar com isso.

Abordagem 1: O Parâmetro default=

Passe uma função para default= que converta tipos desconhecidos em algo serializável. Essa função só é chamada para objetos que o codificador JSON não sabe como tratar.

Python 3.10+ — default= para datetime, UUID, Decimal
import json
from datetime import datetime
from decimal import Decimal
from uuid import UUID

def json_serial(obj):
    """Serializador de fallback para tipos não-padrão."""
    if isinstance(obj, datetime):
        return obj.isoformat()
    if isinstance(obj, UUID):
        return str(obj)
    if isinstance(obj, Decimal):
        return float(obj)
    raise TypeError(f"Type {type(obj).__name__} is not JSON serializable")

transaction = {
    "txn_id": UUID("a1b2c3d4-e5f6-7890-abcd-ef1234567890"),
    "amount": Decimal("149.99"),
    "currency": "EUR",
    "processed_at": datetime(2026, 3, 15, 14, 30, 0),
    "gateway": "stripe",
}

print(json.dumps(transaction, indent=2, default=json_serial))
# {
#   "txn_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
#   "amount": 149.99,
#   "currency": "EUR",
#   "processed_at": "2026-03-15T14:30:00",
#   "gateway": "stripe"
# }
Aviso:Sempre lance TypeError no final da sua função default= para tipos não reconhecidos. Se você retornar None ou ignorá-los silenciosamente, obterá null na saída sem nenhuma indicação de que dados foram perdidos.

Abordagem 2: Dataclasses com asdict()

Dataclasses do Python fornecem uma definição de tipo adequada para as suas linhas CSV. Use dataclasses.asdict() para converter uma instância de dataclass em um dict simples e, em seguida, passe para json.dumps().

Python 3.10+ — serialização de dataclass
import json
from dataclasses import dataclass, asdict
from datetime import datetime

@dataclass
class ShipmentRecord:
    tracking_id: str
    origin: str
    destination: str
    weight_kg: float
    shipped_at: datetime

def json_serial(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"Not serializable: {type(obj).__name__}")

shipment = ShipmentRecord(
    tracking_id="SHP-9827",
    origin="Lisboa",
    destination="São Paulo",
    weight_kg=1240.5,
    shipped_at=datetime(2026, 3, 12, 8, 0, 0),
)

print(json.dumps(asdict(shipment), indent=2, default=json_serial))
# {
#   "tracking_id": "SHP-9827",
#   "origin": "Lisboa",
#   "destination": "São Paulo",
#   "weight_kg": 1240.5,
#   "shipped_at": "2026-03-12T08:00:00"
# }
Nota:asdict() converte recursivamente dataclasses aninhadas em dicts. Se sua dataclass contiver uma lista de outras dataclasses, toda a árvore é convertida — sem código extra necessário.

Referência de Parâmetros do json.dumps()

Lista completa de argumentos de palavra-chave aceitos por json.dumps() e json.dump(). Ambas as funções aceitam parâmetros idênticos — json.dump() recebe um primeiro argumento adicional para o objeto arquivo.

Parâmetro
Tipo
Padrão
Descrição
obj
Any
(obrigatório)
O objeto Python a serializar — dict, list, str, int, float, bool, None
indent
int | str | None
None
Número de espaços (ou string) por nível de indentação. None = saída compacta em uma linha
sort_keys
bool
False
Ordenar as chaves do dicionário alfabeticamente na saída
ensure_ascii
bool
True
Escapar todos os caracteres não-ASCII como \\uXXXX. Defina False para emitir UTF-8 diretamente
default
Callable | None
None
Função chamada para objetos não serializáveis por padrão — retorne um valor serializável ou lance TypeError
separators
tuple[str, str] | None
None
Substitui (separador_de_item, separador_de_chave). Use (",", ":") para saída compacta sem espaços
skipkeys
bool
False
Ignorar chaves de dict que não sejam str, int, float, bool ou None em vez de lançar TypeError
allow_nan
bool
True
Permitir float("nan"), float("inf"), float("-inf"). Defina False para lançar ValueError nesses valores
cls
Type[JSONEncoder] | None
None
Subclasse personalizada de JSONEncoder para usar no lugar do padrão

csv.DictReader — Lendo CSV em Dicts Python

csv.DictReader é a outra metade do pipeline CSV-para-JSON. Ele envolve um objeto arquivo e produz um dict por linha, usando a primeira linha como nomes de campos. Comparado ao csv.reader (que produz listas simples), o DictReader oferece acesso nomeado às colunas — sem índices mágicos como row[3].

Python 3.10+ — DictReader com delimitador personalizado
import csv
import json

# Arquivo separado por tabulação exportado de banco de dados
with open("user_sessions.tsv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f, delimiter="\t")
    sessions = list(reader)

print(json.dumps(sessions[:2], indent=2))
# [
#   {
#     "session_id": "sess_8f2a91bc",
#     "user_id": "usr_4421",
#     "started_at": "2026-03-15T09:12:00Z",
#     "duration_sec": "342",
#     "pages_viewed": "7"
#   },
#   {
#     "session_id": "sess_3c7d44ef",
#     "user_id": "usr_1187",
#     "started_at": "2026-03-15T09:14:22Z",
#     "duration_sec": "128",
#     "pages_viewed": "3"
#   }
# ]
Aviso:csv.DictReader lê o arquivo inteiro de forma lazy — ele produz linhas uma a uma. Chamar list(reader) carrega todas as linhas na memória. Para arquivos com milhões de linhas, processe-as de forma streaming em vez de coletá-las todas.

Converter CSV de Arquivo e Resposta de API

Dois cenários de produção: ler um arquivo CSV do disco e convertê-lo, e buscar dados CSV de um endpoint de API (muitos serviços de relatório retornam CSV). Ambos precisam de tratamento adequado de erros.

Ler Arquivo CSV → Converter → Gravar JSON

Python 3.10+ — conversão de arquivo com tratamento de erros
import csv
import json
import sys

def csv_to_json_file(csv_path: str, json_path: str) -> int:
    """Converter um arquivo CSV para JSON. Retorna o número de linhas gravadas."""
    try:
        with open(csv_path, "r", encoding="utf-8") as f:
            rows = list(csv.DictReader(f))
    except FileNotFoundError:
        print(f"Error: {csv_path} not found", file=sys.stderr)
        sys.exit(1)
    except csv.Error as e:
        print(f"CSV parse error in {csv_path}: {e}", file=sys.stderr)
        sys.exit(1)

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

    return len(rows)

count = csv_to_json_file("fleet_vehicles.csv", "fleet_vehicles.json")
print(f"Wrote {count} records to fleet_vehicles.json")

Buscar CSV de API → Analisar → JSON

Python 3.10+ — resposta CSV de API para JSON
import csv
import io
import json
import urllib.request

def fetch_csv_as_json(url: str) -> str:
    """Buscar CSV de uma URL e retornar como string JSON."""
    try:
        with urllib.request.urlopen(url, timeout=10) as resp:
            raw = resp.read().decode("utf-8")
    except urllib.error.URLError as e:
        raise RuntimeError(f"Failed to fetch {url}: {e}")

    reader = csv.DictReader(io.StringIO(raw))
    rows = list(reader)

    if not rows:
        raise ValueError("CSV response was empty or had no data rows")

    return json.dumps(rows, indent=2, ensure_ascii=False)

# Exemplo: endpoint de exportação que retorna CSV
try:
    result = fetch_csv_as_json("https://reports.internal/api/v2/daily-metrics.csv")
    print(result)
except (RuntimeError, ValueError) as e:
    print(f"Error: {e}")

Ambos os exemplos usam encoding="utf-8" explícito em cada abertura de arquivo. Isso importa para arquivos CSV com caracteres não-ASCII — nomes acentuados, endereços com caracteres especiais, texto CJK. Sem codificação explícita, o Python usa o padrão do sistema, que no Windows costuma ser cp1252 e vai corromper silenciosamente caracteres multibyte.

Verificando a Saída JSON com json.loads()

Após converter CSV para uma string JSON, você pode verificar o resultado analisando-o de volta com json.loads(). Essa verificação de ida e volta detecta problemas de codificação, sequências de escape quebradas ou concatenação acidental de strings que produziria JSON inválido. Envolva a chamada em um bloco try/except.

Python 3.10+ — validação round-trip
import json

json_string = json.dumps({"order_id": "ORD-7291", "total": 129.99})

# Verificar se é JSON válido analisando de volta
try:
    parsed = json.loads(json_string)
    print(f"Valid JSON with {len(parsed)} keys")
except json.JSONDecodeError as e:
    print(f"Invalid JSON: {e}")
# Valid JSON with 2 keys

Conversão de CSV para JSON pela Linha de Comando

Conversões rápidas pelo terminal — sem arquivo de script necessário. A flag -c do Python executa código inline, e você pode redirecionar o resultado por python3 -m json.tool para formatação.

bash — one-liner CSV para JSON
python3 -c "
import csv, json, sys
rows = list(csv.DictReader(sys.stdin))
json.dump(rows, sys.stdout, indent=2)
" < inventory.csv > inventory.json
bash — redirecionar arquivo CSV e formatar com json.tool
python3 -c "import csv,json,sys; print(json.dumps(list(csv.DictReader(sys.stdin))))" < data.csv | python3 -m json.tool
bash — converter e validar com jq
python3 -c "import csv,json,sys; json.dump(list(csv.DictReader(sys.stdin)),sys.stdout)" < report.csv | jq .
Nota:python3 -m json.tool é o formatador JSON integrado. Ele lê JSON do stdin, valida e imprime com indentação de 4 espaços. Útil para verificar se sua conversão CSV-para-JSON produziu saída válida. Se preferir indentação de 2 espaços ou precisar de filtragem, use jq no lugar.

Alternativa de Alta Performance — orjson

O módulo json integrado funciona bem para a maioria dos arquivos CSV. Mas se você estiver processando conjuntos de dados com dezenas de milhares de linhas em um loop, ou sua API precisa serializar dados derivados de CSV em cada requisição, orjson é 5–10x mais rápido. Ele é escrito em Rust, retorna bytes em vez de str, e serializa nativamente datetime, UUID e arrays numpy sem uma função default= personalizada.

bash — instalar orjson
pip install orjson
Python 3.10+ — CSV para JSON com orjson
import csv
import orjson

with open("telemetry_events.csv", "r", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))

# orjson.dumps() retorna bytes, não str
json_bytes = orjson.dumps(rows, option=orjson.OPT_INDENT_2)

with open("telemetry_events.json", "wb") as f:  # note: "wb" para bytes
    f.write(json_bytes)

print(f"Wrote {len(rows)} events ({len(json_bytes)} bytes)")

A API é ligeiramente diferente: orjson.dumps() retorna bytes e usa flags option= em vez de argumentos de palavra-chave. Abra arquivos em modo de escrita binária ("wb") ao gravar saída do orjson. Se precisar de uma string, chame .decode("utf-8") no resultado.

Saída no Terminal com Destaque de Sintaxe — rich

Depurar conversões CSV-para-JSON no terminal fica mais fácil com saída colorida. A biblioteca rich renderiza JSON com destaque de sintaxe — chaves, strings, números e booleanos recebem cores próprias.

bash — instalar rich
pip install rich
Python 3.10+ — saída JSON com rich
import csv
import json
from rich.console import Console
from rich.syntax import Syntax

console = Console()

with open("deployment_log.csv", "r", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))

json_output = json.dumps(rows[:3], indent=2, ensure_ascii=False)
syntax = Syntax(json_output, "json", theme="monokai", line_numbers=True)
console.print(syntax)
Aviso:rich adiciona códigos de escape ANSI à saída. Não grave saída formatada pelo rich em um arquivo ou resposta de API — ela conterá caracteres de controle invisíveis. Use rich apenas para exibição no terminal.

Trabalhando com Arquivos CSV Grandes

Carregar um arquivo CSV de 500 MB com list(csv.DictReader(f)) aloca todo o conjunto de dados na memória, e então json.dump() constrói a string JSON completa por cima disso. Para arquivos maiores que 50–100 MB, mude para uma abordagem streaming ou grave NDJSON (JSON delimitado por nova linha) — um objeto JSON por linha.

NDJSON — Um Objeto JSON por Linha

Python 3.10+ — streaming CSV para NDJSON
import csv
import json

def csv_to_ndjson(csv_path: str, ndjson_path: str) -> int:
    """Converter CSV para NDJSON, processando uma linha por vez."""
    count = 0
    with open(csv_path, "r", encoding="utf-8") as infile, \
         open(ndjson_path, "w", encoding="utf-8") as outfile:
        for row in csv.DictReader(infile):
            outfile.write(json.dumps(row, ensure_ascii=False) + "\n")
            count += 1
    return count

rows_written = csv_to_ndjson("access_log.csv", "access_log.ndjson")
print(f"Wrote {rows_written} lines to access_log.ndjson")
# Cada linha é um objeto JSON independente:
# {"timestamp":"2026-03-15T09:12:00Z","method":"GET","path":"/api/v2/orders","status":"200"}
# {"timestamp":"2026-03-15T09:12:01Z","method":"POST","path":"/api/v2/payments","status":"201"}

Streaming com ijson para Grandes Entradas JSON

Python 3.10+ — ijson para leitura de JSON grande
import ijson  # pip install ijson

def count_high_value_orders(json_path: str, threshold: float) -> int:
    """Contar pedidos acima de um limite sem carregar o arquivo completo."""
    count = 0
    with open(json_path, "rb") as f:
        for item in ijson.items(f, "item"):
            if float(item.get("total", 0)) > threshold:
                count += 1
    return count

# Processar um arquivo JSON de 2 GB com uso de memória constante
high_value = count_high_value_orders("all_orders.json", 500.0)
print(f"Found {high_value} orders above $500")
Nota:Mude para NDJSON ou streaming quando o CSV ultrapassar 50–100 MB. ijson é para leitura de arquivos JSON grandes — para o lado da escrita, o padrão NDJSON acima mantém o uso de memória constante independente do tamanho do arquivo.

Erros Comuns

Usar json.dumps() e depois gravar no arquivo separadamente

Problema: json.dumps() retorna uma string. Gravá-la com f.write() funciona, mas cria uma string intermediária desnecessária na memória — um desperdício para conjuntos de dados grandes.

Solução: Use json.dump(data, f) para gravar diretamente no objeto arquivo. Ele transmite a saída sem construir a string completa primeiro.

Before · Python
After · Python
json_string = json.dumps(rows, indent=2)
with open("output.json", "w") as f:
    f.write(json_string)  # string intermediária desnecessária
with open("output.json", "w", encoding="utf-8") as f:
    json.dump(rows, f, indent=2, ensure_ascii=False)  # gravação direta
Esquecer de converter valores string do CSV para números

Problema: csv.DictReader retorna todos os valores como strings. A saída JSON contém "quantity": "5" em vez de "quantity": 5, o que quebra consumidores de API com validação de tipos.

Solução: Converta colunas numéricas explicitamente com int() ou float() antes de serializar.

Before · Python
After · Python
rows = list(csv.DictReader(f))
json.dumps(rows)
# [{"port": "8080", "workers": "4"}]  ← strings, não números
rows = list(csv.DictReader(f))
for row in rows:
    row["port"] = int(row["port"])
    row["workers"] = int(row["workers"])
json.dumps(rows)
# [{"port": 8080, "workers": 4}]  ← inteiros corretos
Omitir encoding='utf-8' ao abrir arquivo

Problema: No Windows, a codificação padrão é cp1252. Caracteres não-ASCII (nomes acentuados, texto CJK) ficam corrompidos silenciosamente ou lançam UnicodeDecodeError.

Solução: Sempre passe encoding='utf-8' para open() tanto para leitura do CSV quanto para gravação do JSON.

Before · Python
After · Python
with open("locations.csv", "r") as f:  # usa codificação padrão do sistema
    rows = list(csv.DictReader(f))
with open("locations.csv", "r", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))
Usar str() ou repr() em vez de json.dumps()

Problema: str(my_dict) produz sintaxe Python (aspas simples, True, None) que não é JSON válido. APIs e parsers JSON rejeitam isso.

Solução: Use sempre json.dumps() para produzir JSON válido. Ele converte True para true, None para null e usa aspas duplas.

Before · Python
After · Python
output = str({"active": True, "note": None})
# "{'active': True, 'note': None}"  ← NÃO é JSON válido
output = json.dumps({"active": True, "note": None})
# '{"active": true, "note": null}'  ← JSON válido

json.dumps() vs Alternativas — Comparação Rápida

Método
Saída
JSON Válido
Tipos Personalizados
Velocidade
Requer Instalação
json.dumps()
str
via parâmetro default=
Base
Não (stdlib)
json.dump()
grava em arquivo
via parâmetro default=
Base
Não (stdlib)
csv.DictReader + json
str ou arquivo
via parâmetro default=
Base
Não (stdlib)
pandas to_json()
str ou arquivo
✓ datetime nativo
~2x mais rápido para dados grandes
pip install pandas
orjson.dumps()
bytes
✓ datetime/UUID nativos
5–10x mais rápido
pip install orjson
dataclasses.asdict() + json
str
via parâmetro default=
Base
Não (stdlib)
polars write_json()
str ou arquivo
✓ datetime nativo
~3x mais rápido para dados grandes
pip install polars

Para a maioria das conversões CSV-para-JSON, a combinação da biblioteca padrão csv + json é a escolha certa: zero dependências, vem com o Python, funciona em qualquer lugar. Recorra ao orjson quando o profiling mostrar que a serialização é um gargalo — a diferença de velocidade é real em escala. Use pandas quando também precisar de limpeza, filtragem ou agregação de dados antes de converter para JSON. Se precisar de uma conversão rápida sem escrever código, o conversor online de CSV para JSON resolve instantaneamente.

Perguntas Frequentes

Qual é a diferença entre json.dump() e json.dumps() em Python?

json.dump(obj, arquivo) grava a saída JSON diretamente em um objeto semelhante a arquivo (qualquer objeto com um método .write()). json.dumps(obj) retorna uma string formatada em JSON. Use json.dump() ao gravar em um arquivo, json.dumps() quando precisar do JSON como string Python para logs, incorporação em um payload ou envio por socket. Ambas aceitam os mesmos argumentos de palavra-chave (indent, sort_keys, ensure_ascii, default).

Como converter um dicionário Python em uma string JSON?

Chame json.dumps(seu_dict). O valor retornado é uma str contendo JSON válido. Adicione indent=2 para saída legível. Se o seu dict contiver valores não-ASCII, passe ensure_ascii=False para preservar caracteres como letras acentuadas ou texto CJK.

Python 3.10+
import json

server_config = {"host": "api.internal", "port": 8443, "debug": False}
json_string = json.dumps(server_config, indent=2)
print(json_string)
# {
#   "host": "api.internal",
#   "port": 8443,
#   "debug": false
# }

Como salvar uma lista de dicts Python como arquivo JSON?

Abra um arquivo em modo de escrita com codificação UTF-8 e chame json.dump(sua_lista, f, indent=2, ensure_ascii=False). Use sempre json.dump() (não json.dumps()) para saída em arquivo — ele grava diretamente no identificador de arquivo sem criar uma string intermediária na memória.

Python 3.10+
import json

records = [
    {"order_id": "ORD-4821", "total": 129.99, "currency": "USD"},
    {"order_id": "ORD-4822", "total": 89.50, "currency": "EUR"},
]

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

Por que json.dumps() converte True em true e None em null?

Os booleanos do Python (True, False) e None não são tokens JSON válidos. A especificação JSON usa true, false e null em minúsculas. json.dumps() realiza esse mapeamento automaticamente — True vira true, False vira false, None vira null. Não é necessário converter manualmente. No sentido inverso, json.loads() os mapeia de volta para tipos Python.

Como lidar com objetos datetime ao converter dados CSV para JSON?

Passe uma função default= para json.dumps() que converta objetos datetime em strings ISO 8601. A função default é chamada para qualquer objeto que o json não consiga serializar nativamente. Retorne obj.isoformat() para instâncias de datetime e lance TypeError para qualquer outro tipo.

Python 3.10+
import json
from datetime import datetime

def json_default(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"Not serializable: {type(obj)}")

event = {"action": "login", "timestamp": datetime(2026, 3, 15, 9, 30, 0)}
print(json.dumps(event, default=json_default))
# {"action": "login", "timestamp": "2026-03-15T09:30:00"}

Posso converter CSV para JSON sem pandas?

Sim. A biblioteca padrão do Python tem tudo o que você precisa. Use csv.DictReader para ler cada linha como um dicionário, colete as linhas em uma lista e serialize com json.dump() ou json.dumps(). Nenhuma biblioteca de terceiros é necessária. O pandas só vale a pena adicionar se você também precisar de limpeza de dados, inferência de tipos ou já o estiver usando em outro lugar no projeto.

Python 3.10+
import csv
import json

with open("inventory.csv", "r", encoding="utf-8") as csv_file:
    rows = list(csv.DictReader(csv_file))

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

Para uma alternativa com um clique sem escrever nenhum Python, experimente o conversor CSV para JSON — cole seus dados CSV e obtenha saída JSON formatada imediatamente.

Ferramentas Relacionadas

MS
Maria SantosBackend Developer

Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.

PS
Priya SharmaRevisor técnico

Priya is a data scientist and machine learning engineer who has worked across the full Python data stack — from raw data ingestion and cleaning to model deployment and monitoring. She is passionate about reproducible research, Jupyter-based workflows, and the practical engineering side of ML. She writes about NumPy, Pandas, data serialisation, and the Python patterns that make data pipelines reliable at scale.