Manipulação de arquivos
Esta aula aborda a manipulação de arquivos em Python, cobrindo a função open e seus modos, o uso do context manager with, as operações de leitura e escrita, e a importância do encoding. Ao final, você terá uma base sólida para lidar com arquivos de forma eficiente e segura.
Manipular arquivos é uma tarefa essencial em praticamente qualquer programa Python, seja para ler dados de configuração, salvar resultados de processamento ou persistir informações entre execuções. Nesta aula, você aprenderá a trabalhar com arquivos de texto e binários usando a função embutida open(), além de boas práticas como o uso de context managers e a especificação correta de encoding.
Dominar a leitura e escrita de arquivos é fundamental para construir aplicações reais, como scripts de automação, análise de dados e web scraping. Vamos explorar desde os conceitos básicos até detalhes que evitam erros comuns, garantindo que seu código seja robusto e portável.
open e modos
A função open() é a porta de entrada para qualquer operação com arquivos. Ela recebe como primeiro argumento o caminho do arquivo e, opcionalmente, um segundo argumento que especifica o modo de abertura. O modo define se você vai ler, escrever, anexar dados, trabalhar com binário ou texto, entre outros.
Os modos mais comuns são: 'r' (leitura, padrão), 'w' (escrita, sobrescreve o conteúdo existente), 'a' (anexar, adiciona ao final), 'x' (criação exclusiva, falha se o arquivo existir) e 'b' (modo binário), que pode ser combinado com os anteriores (ex.: 'rb', 'wb'). Além disso, há o modificador '+' para leitura e escrita simultâneas (ex.: 'r+').
Ao abrir um arquivo, é importante considerar o diretório atual e usar caminhos relativos ou absolutos. O Python também oferece o módulo pathlib para manipulação mais moderna, mas open() continua sendo a base.
Exemplo de abertura em diferentes modos:
# Abre para leitura (padrão)
arquivo = open('dados.txt', 'r')
# Abre para escrita (sobrescreve)
arquivo = open('dados.txt', 'w')
# Abre para anexar (adiciona ao final)
arquivo = open('dados.txt', 'a')
# Abre para criação exclusiva
arquivo = open('novo.txt', 'x')
# Abre em modo binário para leitura
arquivo = open('imagem.png', 'rb')
# Abre para leitura e escrita
arquivo = open('dados.txt', 'r+')
Lembre-se de sempre fechar o arquivo após o uso, pois deixá-lo aberto pode causar vazamento de recursos. No entanto, a maneira mais segura é usar o context manager, que veremos a seguir.
with (context manager)
O with é uma declaração que cria um contexto de execução, garantindo que o arquivo seja fechado automaticamente ao final do bloco, mesmo que ocorra uma exceção. Isso elimina a necessidade de chamar close() manualmente e torna o código mais limpo e seguro.
A sintaxe é with open(...) as variavel:. Dentro do bloco, você usa a variável para realizar operações de leitura ou escrita. Ao sair do bloco, o Python chama o método __exit__ do objeto arquivo, que fecha o arquivo. Esse padrão é amplamente recomendado pela comunidade Python.
Exemplo básico:
with open('dados.txt', 'r') as arquivo:
conteudo = arquivo.read()
print(conteudo)
# O arquivo é fechado automaticamente aqui
Além da segurança, o with também funciona com outros recursos, como conexões de rede e locks, mas aqui focamos em arquivos. É uma boa prática usar with sempre que possível.
Lendo e escrevendo
Python oferece vários métodos para ler e escrever conteúdo em arquivos. Para leitura, temos read() (lê todo o conteúdo como string), readline() (lê uma linha por vez) e readlines() (lê todas as linhas e retorna uma lista). Para escrita, usamos write() para escrever uma string e writelines() para escrever uma lista de strings.
É importante notar que write() não adiciona quebras de linha automaticamente; você deve incluir '\n' quando necessário. Além disso, ao trabalhar com arquivos grandes, é mais eficiente ler linha por linha do que carregar tudo na memória.
Exemplo de leitura completa:
with open('dados.txt', 'r') as f:
conteudo = f.read()
print(conteudo)
Exemplo de leitura linha por linha:
with open('dados.txt', 'r') as f:
for linha in f:
print(linha.strip()) # strip remove a quebra de linha
Exemplo de escrita:
with open('saida.txt', 'w') as f:
f.write('Linha 1\n')
f.write('Linha 2\n')
f.writelines(['Linha 3\n', 'Linha 4\n'])
Para anexar, use o modo 'a':
with open('saida.txt', 'a') as f:
f.write('Mais uma linha\n')
Lembre-se de que, ao escrever, o arquivo é criado se não existir (nos modos 'w' e 'a'), e no modo 'w' o conteúdo anterior é truncado.
Encoding
Encoding (codificação) define como os caracteres são representados em bytes. Em Python 3, as strings são Unicode, mas ao ler ou escrever em arquivos, precisamos especificar a codificação para que os bytes sejam interpretados corretamente. O padrão é UTF-8, que é amplamente usado e suporta todos os caracteres Unicode.
Se você não especificar o encoding, o Python usa o padrão da plataforma, que pode variar (ex.: UTF-8 no Linux, cp1252 no Windows). Isso pode causar erros ou corromper dados ao ler arquivos com caracteres especiais. Portanto, é sempre recomendado passar o parâmetro encoding para open().
Exemplo de leitura com encoding explícito:
with open('dados.txt', 'r', encoding='utf-8') as f:
conteudo = f.read()
print(conteudo)
Exemplo de escrita com encoding:
with open('saida.txt', 'w', encoding='utf-8') as f:
f.write('Olá, mundo!\n')
Ao lidar com arquivos que não estão em UTF-8, você pode especificar outros encodings, como 'latin-1' ou 'cp1252'. Se encontrar um erro de UnicodeDecodeError, significa que o encoding especificado não corresponde ao conteúdo do arquivo. Nesse caso, tente outros encodings ou use o parâmetro errors para lidar com erros (ex.: errors='ignore').
Boas práticas: sempre use UTF-8 por padrão, pois é o mais universal e recomendado para novos projetos.
Boas práticas e observações finais
Ao trabalhar com arquivos, siga estas recomendações para evitar problemas:
- Sempre use
withpara garantir o fechamento automático. - Especifique o encoding explicitamente, especialmente se o arquivo contiver caracteres não ASCII.
- Prefira ler linha por linha em arquivos grandes para economizar memória.
- Use
pathlib.Pathpara manipular caminhos de forma mais intuitiva e multiplataforma. - Trate exceções como
FileNotFoundErrorePermissionErrorpara tornar o programa robusto.
Com esses conhecimentos, você está pronto para integrar a manipulação de arquivos em seus projetos Python de forma eficiente e segura.
Referências
- Documentação oficial: open()
- Tutorial Python: Leitura e escrita de arquivos
- Documentação: declaração with
- Python Unicode HOWTO
- Módulo io — ferramentas de entrada/saída
- pathlib — caminhos de arquivos orientados a objeto
Exercícios
-
Crie um arquivo chamado 'exercicio1.txt' e escreva nele as três linhas: 'Python', 'é', 'incrível'. Use o modo 'w' e depois leia e imprima o conteúdo.
✓ Resposta:
with open('exercicio1.txt', 'w', encoding='utf-8') as f: f.write('Python\n') f.write('é\n') f.write('incrível\n') with open('exercicio1.txt', 'r', encoding='utf-8') as f: print(f.read()) -
Escreva um programa que leia um arquivo 'dados.txt' e conte quantas linhas ele possui. Use o modo 'r' e o loop
for.✓ Resposta:contador = 0 with open('dados.txt', 'r', encoding='utf-8') as f: for linha in f: contador += 1 print(f'Número de linhas: {contador}') -
Dada uma lista de nomes
nomes = ['Ana', 'João', 'Maria'], escreva cada nome em uma linha de um arquivo 'nomes.txt' (modo 'w'). Depois, abra o arquivo e exiba os nomes em ordem alfabética.✓ Resposta:nomes = ['Ana', 'João', 'Maria'] with open('nomes.txt', 'w', encoding='utf-8') as f: for nome in nomes: f.write(nome + '\n') with open('nomes.txt', 'r', encoding='utf-8') as f: linhas = [linha.strip() for linha in f] linhas.sort() for nome in linhas: print(nome) -
O que acontece se você tentar abrir um arquivo inexistente no modo 'r'? Escreva um código que trate essa exceção usando
try/excepte exiba uma mensagem amigável.✓ Resposta:try: with open('nao_existe.txt', 'r', encoding='utf-8') as f: conteudo = f.read() except FileNotFoundError: print('O arquivo não foi encontrado.') -
Crie um programa que copie o conteúdo de um arquivo 'origem.txt' para 'destino.txt'. Use o modo 'r' para ler e 'w' para escrever. Garanta que o encoding seja UTF-8 em ambos.
✓ Resposta:
with open('origem.txt', 'r', encoding='utf-8') as origem: conteudo = origem.read() with open('destino.txt', 'w', encoding='utf-8') as destino: destino.write(conteudo)