Menu
Testar no Playground

Manipulação de arquivos em Python: ler, escrever e adicionar com segurança

Como ler e escrever arquivos em Python — a instrução with, texto vs binário e a API moderna baseada em caminhos, mais segura.

Arquivos são só strings com um caminho

A maioria dos programas eventualmente precisa ler ou escrever um arquivo — configs, dados de usuário, logs, exportações CSV, pequenos caches. O Python mantém isso simples com uma função embutida, open(), mais um bloco with para garantir que as coisas fechem limpas.

Vamos passar pelos casos comuns.

Lendo um arquivo inteiro

A leitura mais simples:

with open("notes.txt") as f:
    contents = f.read()

print(contents)

open("notes.txt") abre o arquivo para leitura (padrão). O bloco with significa que o Python vai fechar o arquivo quando você sai do bloco — mesmo se uma exceção é lançada. Uma vez fechado, você não pode mais usar f; o texto vive em contents.

contents é uma única string contendo o arquivo inteiro. Tudo bem para arquivos pequenos; ruim para um log de 2 GB.

Lendo linha por linha

Para arquivos maiores, itere em vez de ler tudo para a memória:

with open("big.log") as f:
    for line in f:
        if "ERROR" in line:
            print(line.strip())

Cada iteração produz uma linha incluindo a quebra de linha final — por isso .strip() aparece com tanta frequência. Se quer uma lista de linhas, f.readlines() faz isso, mas geralmente a iteração direta é o que você quer.

Escrevendo um arquivo

Para escrever, passe o modo como segundo argumento:

with open("output.txt", "w") as f:
    f.write("first line\n")
    f.write("second line\n")

Duas coisas para notar:

  • "w" sobrescreve. Se output.txt já existe, o conteúdo dele sumiu no momento em que open roda.
  • Você adiciona as quebras de linha. f.write("hello") escreve exatamente esses cinco caracteres — sem newline no fim.

Para adicionar em vez de sobrescrever:

with open("output.txt", "a") as f:
    f.write("another line\n")

Você também pode alimentar várias linhas de uma vez com writelines:

lines = ["a\n", "b\n", "c\n"]
with open("letters.txt", "w") as f:
    f.writelines(lines)

Mesma regra: você coloca as quebras de linha.

print tem um argumento file, que é um jeito fácil de escrever sem newlines manuais:

with open("log.txt", "w") as f:
    print("started", file=f)
    print("finished", file=f)

Cada print escreve os argumentos mais uma quebra de linha no fim. Para saída casual, muitas vezes é a forma mais gentil.

Modo texto vs binário

Por padrão, open está em modo texto. O Python decodifica bytes em strings (usando UTF-8 por padrão em plataformas modernas) e cuida da tradução de quebras de linha.

Para imagens, PDFs, arquivos compilados ou qualquer coisa que não é texto, abra em modo binário adicionando "b" ao modo:

with open("image.png", "rb") as f:
    data = f.read()

print(len(data))  # number of bytes

with open("image_copy.png", "wb") as f:
    f.write(data)

Em modo binário, você recebe objetos bytes em vez de str, e o Python não toca em quebras de linha.

Especificando encoding

Para arquivos de texto, seja explícito sobre encoding. UTF-8 é quase sempre certo em 2026:

with open("notes.txt", encoding="utf-8") as f:
    contents = f.read()

Se você está lidando com arquivos antigos de uma empresa só Windows, pode ver cp1252 ou latin-1. Chutar errado te dá caracteres embaralhados ou um UnicodeDecodeError.

pathlib: o jeito moderno de lidar com caminhos

O módulo pathlib da biblioteca padrão te dá uma API mais ergonômica do que strings cruas:

from pathlib import Path

path = Path("notes.txt")

# Simple read and write.
contents = path.read_text(encoding="utf-8")
path.write_text("new contents\n", encoding="utf-8")

# Build paths without worrying about / vs \.
data_dir = Path("data")
log_path = data_dir / "today.log"

print(log_path)
print(log_path.exists())
print(log_path.suffix)       # ".log"
print(log_path.stem)         # "today"
print(log_path.parent)       # "data"

Path.read_text() e write_text() são atalhos para o padrão with open(...) as f quando você só quer ler e escrever de uma vez. Para iteração linha por linha, você ainda usa open ou path.open().

Um pequeno exemplo de ponta a ponta

Ler uma lista de itens de um arquivo, filtrar e escrever o resultado em outro:

from pathlib import Path

source = Path("items.txt")
destination = Path("filtered.txt")

items = source.read_text().splitlines()
kept = [item for item in items if item and not item.startswith("#")]

destination.write_text("\n".join(kept) + "\n")

print(f"Kept {len(kept)} items out of {len(items)}")

splitlines() é o companheiro orientado a linha do join. Divide em quebras de linha sem mantê-las — útil quando você vai rejuntar as partes mesmo.

Quando as coisas dão errado

Abrir um arquivo que não existe lança FileNotFoundError. Tentar ler um arquivo sem permissão lança PermissionError. Os dois são subclasses de OSError, que por sua vez é subclasse de Exception — vamos falar de tratamento apropriado de exceções na próxima página.

Por enquanto, uma prévia rápida do que tratamento de erro parece:

from pathlib import Path

path = Path("maybe.txt")

try:
    contents = path.read_text()
except FileNotFoundError:
    print("File doesn't exist — starting fresh.")
    contents = ""

print(repr(contents))

Hábitos principais

  • Sempre use with open(...) em vez de open puro + close manual.
  • Sempre passe encoding= para arquivos de texto; UTF-8 por padrão.
  • Itere arquivos grandes linha por linha; não chame .read() neles inteiros.
  • Para caminhos e padrões comuns de leitura/escrita, use pathlib — vai te poupar muita ginástica de string.

Na sequência: JSON. A maioria dos arquivos de texto do mundo real que você lê não são linhas simples — são estruturados, e JSON é o formato mais comum. Os mesmos hábitos de with open(...) se carregam direto.

Perguntas frequentes

Como leio um arquivo em Python?

Use open() com a instrução with, que fecha o arquivo automaticamente quando você termina. with open('file.txt') as f: contents = f.read() lê o arquivo inteiro numa string. Para linha por linha, percorra o objeto de arquivo diretamente: for line in f:.

Qual a diferença entre os modos 'r', 'w' e 'a' do open?

'r' é leitura (padrão). 'w' é escrita — cria o arquivo ou trunca se existe. 'a' é append — adiciona ao fim do arquivo sem apagar o que está lá. Adicione 'b' para modo binário ou '+' para leitura+escrita.

Por que usar with open em vez de open() puro?

A instrução with garante que o arquivo fecha mesmo se um erro acontece no meio. Sem with, você tem que chamar .close() você mesmo e lembrar em caminhos de erro. with é mais seguro e menos código.

Aprenda a programar com o Coddy

COMEÇAR