configparser no Python: arquivos INI

Publicado em: 16/08/2026
Tempo de leitura: 6 minutos
Diagrama de arquivos e sistema representando configurações INI com configparser no Python

O módulo configparser no Python lê e grava arquivos de configuração no estilo INI, organizados em seções, opções e valores textuais. Ele é adequado para aplicações desktop, ferramentas de linha de comando, scripts administrativos e programas que precisam permitir ajustes simples sem exigir JSON ou YAML.

O formato INI não possui uma especificação única e universal. Cada aplicação pode adotar regras diferentes para comentários, maiúsculas, delimitadores, valores vazios e interpolação. Por isso, configure o parser explicitamente e documente o dialeto aceito.

Crie um arquivo INI básico

[servidor]
host = 127.0.0.1
porta = 8080
debug = false

[logs]
nivel = INFO
arquivo = logs/app.log

Cada cabeçalho entre colchetes define uma seção. As opções usam = ou : como delimitador por padrão.

Leia a configuração

import configparser

config = configparser.ConfigParser()
lidos = config.read("app.ini", encoding="utf-8")

if not lidos:
    raise FileNotFoundError("app.ini não foi carregado")

host = config["servidor"]["host"]
porta = config["servidor"].getint("porta")
debug = config["servidor"].getboolean("debug")

read() ignora silenciosamente arquivos que não consegue abrir e devolve a lista dos que foram lidos. Se um arquivo é obrigatório, verifique o retorno ou use read_file() com um handle já aberto.

Todos os valores são strings

O parser não infere tipos automaticamente. Use getint(), getfloat() e getboolean().

timeout = config["servidor"].getfloat("timeout", fallback=5.0)
workers = config["servidor"].getint("workers", fallback=4)
ativo = config["servidor"].getboolean("ativo", fallback=True)

getboolean() reconhece valores como yes/no, true/false, on/off e 1/0. Não use bool("false"), pois qualquer string não vazia é verdadeira.

Use fallbacks corretamente

No proxy de uma seção, o segundo argumento de get() é o fallback:

nivel = config["logs"].get("nivel", "INFO")

Na API do parser, use a palavra-chave fallback:

nivel = config.get("logs", "nivel", fallback="INFO")

Valores da seção DEFAULT têm prioridade sobre o fallback. Isso pode surpreender quando uma opção parece ausente na seção, mas é herdada.

Defina valores padrão

[DEFAULT]
timeout = 10
retries = 3

[api]
url = https://api.example.com

[worker]
retries = 5

As opções de DEFAULT ficam visíveis em todas as seções. Remover uma sobrescrita faz o valor padrão reaparecer; ele não pertence fisicamente à seção.

Leia vários arquivos em camadas

Arquivos lidos depois sobrescrevem opções conflitantes, mas preservam as demais.

config.read(
    ["defaults.ini", "site.ini", "usuario.ini"],
    encoding="utf-8",
)

Uma arquitetura comum usa defaults versionados, configuração do servidor e overrides do usuário. Não use arquivos opcionais para parâmetros críticos sem validar que os valores essenciais estão presentes.

Use read_file para arquivos obrigatórios

from pathlib import Path

caminho = Path("defaults.ini")
with caminho.open(encoding="utf-8") as arquivo:
    config.read_file(arquivo, source=str(caminho))

Erros de sintaxe e abertura são propagados. O parâmetro source melhora a mensagem de diagnóstico.

Leia strings e dicionários

read_string() é útil em testes e conteúdo recebido de uma fonte controlada.

config.read_string("""
[servico]
url = https://example.com
""", source="configuração embutida")

read_dict() carrega uma estrutura de mapeamentos e converte valores para texto.

config.read_dict({
    "servidor": {"porta": 8080, "debug": False},
})

Entenda maiúsculas e minúsculas

Por padrão, nomes de seções diferenciam maiúsculas, mas opções não. As chaves são normalizadas para minúsculas por optionxform().

config = configparser.ConfigParser()
config.read_string("""
[Secao]
MinhaChave = valor
""")
print(list(config["Secao"]))
# ['minhachave']

Para preservar a caixa:

config.optionxform = str

Faça isso antes de ler dados. A função de transformação deve ser idempotente.

Interpolação básica

O ConfigParser usa BasicInterpolation por padrão.

[caminhos]
base = /opt/minhaapp
logs = %(base)s/logs
cache = %(base)s/cache

Para incluir um caractere percentual literal, escreva %%. A interpolação acontece quando o valor é obtido, não durante a leitura.

Interpolação estendida

ExtendedInterpolation usa a sintaxe ${seção:opção} e permite referências entre seções.

from configparser import ConfigParser, ExtendedInterpolation

config = ConfigParser(interpolation=ExtendedInterpolation())
[comum]
raiz = /srv/app

[logs]
dir = ${comum:raiz}/logs

Use $$ para um cifrão literal. Ciclos e referências ausentes geram exceções de interpolação.

Desative a interpolação quando necessário

Valores como padrões, templates e senhas podem conter % ou $. Se a interpolação não faz parte do formato:

config = configparser.ConfigParser(interpolation=None)

Também é possível usar get(..., raw=True) para uma leitura específica.

Conversores personalizados

O parâmetro converters cria novos métodos get*.

from pathlib import Path

config = configparser.ConfigParser(
    converters={"path": Path, "lista": lambda v: [x.strip() for x in v.split(",")]},
)

pasta = config["logs"].getpath("arquivo")
origens = config["cors"].getlista("origens")

Conversão não é validação completa. Verifique faixas, extensões, existência, permissões e regras de negócio após converter.

Personalize valores booleanos

config.BOOLEAN_STATES = {
    "habilitado": True,
    "desabilitado": False,
}

Um vocabulário customizado pode facilitar arquivos localizados, mas reduz portabilidade. Documente os valores aceitos.

Arquivos com opções sem valor

Alguns formatos usam flags sem delimitador.

config = configparser.ConfigParser(allow_no_value=True)
[recursos]
modo_seguro
auditoria

Essas opções retornam None. No Python recente, continuar uma opção sem valor com linha indentada gera MultilineContinuationError.

Seções sem nome

Python 3.13 adicionou suporte opcional a uma seção inicial sem cabeçalho.

config = configparser.ConfigParser(allow_unnamed_section=True)
config.read_string("""
chave = valor

[outra]
x = 1
""")
valor = config[configparser.UNNAMED_SECTION]["chave"]

Ative o recurso apenas quando precisar compatibilidade com um formato existente.

Comentários e valores multilinha

Por padrão, # e ; iniciam comentários em linhas próprias. Comentários inline ficam desativados porque não existe escape confiável para os prefixos.

Valores multilinha precisam ser indentados além da chave:

[mensagem]
texto = primeira linha
    segunda linha
    terceira linha

Quando arquivos são editados por pessoas, considere empty_lines_in_values=False para reduzir ambiguidades visuais.

Modo estrito

strict=True, padrão atual, rejeita seções e opções duplicadas dentro da mesma fonte.

Essa validação captura erros de digitação e colisões causadas pela normalização de caixa. Mantenha-a ativa em novos projetos.

Trate exceções de forma clara

try:
    with open("app.ini", encoding="utf-8") as arquivo:
        config.read_file(arquivo)
except configparser.MissingSectionHeaderError as erro:
    raise RuntimeError("Arquivo sem cabeçalho de seção") from erro
except configparser.DuplicateOptionError as erro:
    raise RuntimeError("Opção duplicada") from erro
except configparser.InterpolationError as erro:
    raise RuntimeError("Interpolação inválida") from erro

Inclua fonte e linha no diagnóstico, mas não registre valores secretos.

Grave a configuração

from pathlib import Path

config["servidor"]["porta"] = "9090"
with Path("app.ini").open("w", encoding="utf-8") as arquivo:
    config.write(arquivo)

Todos os valores devem ser strings. No Python 3.14, write() gera InvalidWriteError se a representação não puder ser lida corretamente depois.

Escreva de forma atômica

Não sobrescreva diretamente um arquivo importante. Grave em um arquivo temporário no mesmo diretório, faça flush(), sincronize e substitua com os.replace().

import os
from pathlib import Path
from tempfile import NamedTemporaryFile

destino = Path("app.ini")
with NamedTemporaryFile("w", encoding="utf-8", dir=destino.parent, delete=False) as temp:
    config.write(temp)
    temp.flush()
    os.fsync(temp.fileno())
    temporario = temp.name
os.replace(temporario, destino)

Controle permissões e proprietário. Em escrita concorrente, use locking ou um serviço central de configuração.

Comentários não são preservados

Ao ler e escrever novamente, comentários e formatação original são perdidos. Se usuários mantêm documentação importante no arquivo, evite reescrevê-lo automaticamente ou use uma biblioteca que preserve o layout.

Não guarde segredos no INI

Arquivos INI são texto simples. Senhas, tokens e chaves devem vir de um gerenciador de segredos, variável de ambiente protegida ou credencial do sistema. Se um segredo precisar ser referenciado, armazene apenas seu identificador.

O guia de site no Python explica caminhos de instalação e ambientes; importlib.resources ajuda a distribuir defaults dentro de pacotes; e fileinput no Python trata processamento de vários arquivos.

Valide depois de ler

def carregar_servidor(config):
    porta = config["servidor"].getint("porta")
    if not 1 <= porta <= 65535:
        raise ValueError("porta fora da faixa")

    host = config["servidor"].get("host", "127.0.0.1").strip()
    if not host:
        raise ValueError("host vazio")

    return host, porta

O parser garante estrutura e conversões básicas; seu aplicativo deve validar semântica.

ConfigParser versus TOML e JSON

INI é simples e amigável para configurações pequenas. TOML possui especificação mais rigorosa e tipos nativos; JSON é interoperável, mas não aceita comentários. Escolha o formato pela complexidade, ecossistema e necessidade de edição humana.

Boas práticas

  • Use UTF-8 explicitamente.
  • Mantenha strict=True.
  • Verifique arquivos obrigatórios.
  • Defina o comportamento de caixa.
  • Desative interpolação se não for necessária.
  • Valide valores após converter.
  • Escreva atomicamente.
  • Não armazene segredos.

Conclusão

O configparser no Python oferece uma interface madura para configurações INI, com seções, defaults, camadas, interpolação e conversores. Ele funciona bem quando o formato permanece simples e claramente documentado.

Consulte a documentação oficial do configparser e a documentação do tomllib.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Módulo de memória RAM representando gerenciamento de objetos com gc no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    gc no Python: controle o coletor

    Aprenda gc no Python para controlar coleta cíclica, analisar objetos rastreados, diagnosticar vazamentos e observar pausas.

    Ler mais

    Tempo de leitura: 7 minutos
    16/08/2026
    Linhas de código representando rastreamento de execução com trace no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    trace no Python: rastreie execução

    Aprenda trace no Python para contar linhas, rastrear execução, listar funções, acumular cobertura e filtrar módulos.

    Ler mais

    Tempo de leitura: 6 minutos
    16/08/2026
    Notebook com gráficos de desempenho representando análise de perfis com pstats no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pstats no Python: analise perfis

    Aprenda pstats no Python para ordenar, filtrar, combinar e interpretar perfis do cProfile, callers, callees e tempos cumulativos.

    Ler mais

    Tempo de leitura: 6 minutos
    15/08/2026
    Notebook com código representando exemplos executáveis testados com doctest no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    doctest no Python: teste exemplos

    Aprenda doctest no Python para executar exemplos em docstrings e arquivos, normalizar saídas e integrar documentação ao CI.

    Ler mais

    Tempo de leitura: 6 minutos
    15/08/2026
    Código em tela representando navegação de classes e funções com pyclbr no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pyclbr no Python: inspecione módulos

    Aprenda pyclbr no Python para listar classes, funções, métodos e definições aninhadas sem importar nem executar o módulo.

    Ler mais

    Tempo de leitura: 6 minutos
    15/08/2026
    Monitor com código binário representando instruções opcode do bytecode do Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    opcode no Python: explore o bytecode

    Aprenda opcode no Python para mapear instruções de bytecode, argumentos, saltos, caches e efeitos de pilha usando dis.

    Ler mais

    Tempo de leitura: 6 minutos
    15/08/2026