Usando with open

Entenda uma forma segura e prática de abrir arquivos sem esquecer de fechá-los.

Nas lições anteriores, você sempre abriu arquivos com open() e precisou lembrar de chamar close() ao final. Mas e se o programa travar no meio do caminho? E se ocorrer um erro antes de chegar no close()? O arquivo pode ficar aberto indefinidamente.

O with open resolve esse problema de uma vez por todas.

O problema com o open() e close() separados

Veja este exemplo com um possível erro:

arquivo = open("notas.txt", "r", encoding="utf-8")
conteudo = arquivo.read()
resultado = int(conteudo)  # E se o arquivo tiver letras? Erro aqui!
arquivo.close()  # Esta linha nunca será executada se der erro acima

Se int(conteudo) gerar um erro, o arquivo.close() nunca é chamado. O arquivo fica "preso", e isso pode causar problemas — especialmente em programas maiores ou que rodam por muito tempo.

A solução: with open

O with open é uma forma especial de abrir arquivos que garante o fechamento automático — mesmo que ocorra um erro no meio do caminho. Pense nele como uma sala com porta automática: ao entrar, a porta abre; ao sair (seja pela saída normal ou por uma emergência), ela fecha sozinha.

A sintaxe é:

with open("arquivo.txt", "r", encoding="utf-8") as arquivo:
   conteudo = arquivo.read()
   print(conteudo)
# Aqui o arquivo já está fechado automaticamente!

O as arquivo é simplesmente o nome que damos ao arquivo aberto dentro do bloco. Você pode escolher qualquer nome — arquivo, f, doc, o que preferir.

Importante: Tudo que você quiser fazer com o arquivo deve estar dentro do bloco with, ou seja, com indentação. Quando o bloco termina, o arquivo é fechado automaticamente.

Comparando: com e sem with

Veja a mesma operação escrita das duas formas:

Sem with (forma antiga):

arquivo = open("mensagem.txt", "r", encoding="utf-8")
conteudo = arquivo.read()
print(conteudo)
arquivo.close()  # Você precisa lembrar de fechar!

Com with (forma recomendada):

with open("mensagem.txt", "r", encoding="utf-8") as arquivo:
   conteudo = arquivo.read()
   print(conteudo)
# Fechamento automático — sem necessidade de close()

O resultado é idêntico, mas a segunda versão é mais segura e mais curta.

Usando with para leitura

Você pode usar todas as formas de leitura que aprendeu anteriormente dentro do with:

Lendo tudo com read():

with open("poema.txt", "r", encoding="utf-8") as arquivo:
   conteudo = arquivo.read()
   print(conteudo)

Lendo linha por linha com for:

with open("poema.txt", "r", encoding="utf-8") as arquivo:
   for linha in arquivo:
       print(linha.strip())

Lendo como lista com readlines():

with open("poema.txt", "r", encoding="utf-8") as arquivo:
   linhas = arquivo.readlines()

# O arquivo já está fechado aqui, mas a lista ainda está disponível
print(f"O poema tem {len(linhas)} linhas.")

Perceba que no último exemplo, a variável linhas foi criada dentro do with mas é usada fora dele. Isso é totalmente válido — o arquivo foi fechado, mas os dados já estão guardados na variável.

Usando with para escrita

O with funciona igualmente bem para escrever em arquivos:

Criando ou sobrescrevendo com "w":

with open("lista.txt", "w", encoding="utf-8") as arquivo:
   arquivo.write("Item 1: maçã\n")
   arquivo.write("Item 2: banana\n")
   arquivo.write("Item 3: uva\n")
# Arquivo fechado e salvo automaticamente!

Adicionando ao final com "a":

with open("lista.txt", "a", encoding="utf-8") as arquivo:
   arquivo.write("Item 4: melancia\n")

Por que preferir sempre o with?

Situação open() + close() with open()
Código sem erros Funciona Funciona
Erro no meio do bloco close() não é chamado ❌ Fecha automaticamente ✅
Esqueceu de fechar Arquivo fica aberto ❌ Impossível esquecer ✅
Legibilidade Mais verboso Mais limpo e direto ✅

O with open() é considerado a forma idiomática do Python — ou seja, a forma que a comunidade reconhece como correta e recomendada. Sempre que trabalhar com arquivos, prefira usá-lo.

Exemplo prático: agenda de contatos

Vamos criar um programa completo que usa with open para salvar e exibir uma pequena agenda:

def salvar_contato(nome, telefone, nome_arquivo):
   with open(nome_arquivo, "a", encoding="utf-8") as arquivo:
       arquivo.write(f"{nome}:{telefone}\n")
   print(f"Contato '{nome}' salvo com sucesso!")

def listar_contatos(nome_arquivo):
   print("\n=== Agenda de Contatos ===")
   with open(nome_arquivo, "r", encoding="utf-8") as arquivo:
       linhas = arquivo.readlines()

   if not linhas:
       print("Nenhum contato cadastrado.")
       return

   for numero, linha in enumerate(linhas, start=1):
       nome, telefone = linha.strip().split(":")
       print(f"{numero}. {nome} — {telefone}")

# Programa principal
arquivo_agenda = "agenda.txt"

salvar_contato("Ana Silva", "(11) 99999-1111", arquivo_agenda)
salvar_contato("Bruno Costa", "(21) 88888-2222", arquivo_agenda)
salvar_contato("Carla Dias", "(31) 77777-3333", arquivo_agenda)

listar_contatos(arquivo_agenda)

Saída:

Contato 'Ana Silva' salvo com sucesso!
Contato 'Bruno Costa' salvo com sucesso!
Contato 'Carla Dias' salvo com sucesso!

=== Agenda de Contatos ===
1. Ana Silva — (11) 99999-1111
2. Bruno Costa — (21) 88888-2222
3. Carla Dias — (31) 77777-3333

O que aprendemos nesta lição

Nesta lição, você aprendeu que:

  • O with open() garante o fechamento automático do arquivo, mesmo que ocorra um erro no meio da execução.
  • A sintaxe with open("arquivo.txt", "r") as arquivo: abre o arquivo e o nomeia para uso dentro do bloco.
  • Todo o código que usa o arquivo deve estar dentro do bloco with (com indentação).
  • O with open() também funciona com os modos: "r", "w" e "a", e com os métodos: read(), readline(), readlines(), write() e writelines().
  • O with open() é a forma recomendada pela comunidade Python para trabalhar com arquivos — mais segura e mais legível que usar open() e close() separados.