Arquivos e exceções em Python

Aprenda a fazer programas Python trabalharem com arquivos e lidarem com erros. Leia arquivos de texto inteiros ou linha por linha, grave e acrescente texto com segurança usando instruções with e encontre arquivos com caminhos relativos e absolutos e com pathlib. Leia e grave dados CSV com o módulo csv, incluindo linhas como dicionários. Em seguida, capture os erros esperados com try e except, use else e finally, lance suas próprias exceções com mensagens claras e crie programas que informem sobre arquivos ausentes e dados inválidos em vez de encerrá-los inesperadamente.

BásicoAula 8 de 10 do curso Curso de Introdução à programação com Python

O que você vai aprender

  1. Abra arquivos de texto, leia seu conteúdo da forma adequada à tarefa, grave e acrescente texto sem perder dados e processe um arquivo linha por linha para buscar, contar e filtrar.
    • Abra um arquivo de texto e leia seu conteúdo
      Use open() para conectar um programa a um arquivo de texto, escolha a maneira adequada de lê-lo e transforme o texto lido em dados que você possa usar.
    • Feche arquivos automaticamente com a instrução with
      Use with open(...) as f: para que os arquivos sejam fechados no momento certo, mesmo quando algo der errado.
    • Grave e acrescente texto a arquivos
      Escolha o modo adequado para criar, sobrescrever ou ampliar um arquivo e grave texto com write() e print() para que as linhas saiam exatamente como esperado.
    • Busque, conte e filtre linhas em um arquivo
      Processe um arquivo uma linha por vez para encontrar as linhas necessárias, contá-las ou somar seus valores e gravar os resultados em um novo arquivo.
  2. Informe ao Python exatamente onde está um arquivo, entenda por que um programa às vezes não encontra um arquivo que existe e construa caminhos que funcionem no Windows, macOS e Linux.
    • Use caminhos relativos e absolutos corretamente
      Escreva caminhos absolutos e relativos, saiba de qual pasta um caminho relativo parte e evite as armadilhas das barras invertidas em caminhos do Windows.
    • Construa caminhos e gerencie pastas com pathlib
      Use objetos Path do módulo pathlib para juntar, inspecionar e verificar caminhos, encontrar arquivos, criar pastas e ler ou gravar arquivos pequenos em uma etapa.
  3. Use o módulo csv do Python para ler dados tabulares de arquivos CSV, convertê-los em números e gravar os resultados em CSV que programas de planilha possam abrir.
    • Leia dados CSV com csv.reader
      Entenda como um arquivo CSV armazena uma tabela, leia-o linha por linha com csv.reader, pule o cabeçalho e converta os valores necessários.
    • Grave arquivos CSV com csv.writer
      Crie arquivos CSV a partir de listas com csv.writer, para que vírgulas, aspas e terminadores de linha sejam tratados corretamente.
    • Trabalhe com colunas pelo nome usando DictReader e DictWriter
      Leia cada linha CSV como um dicionário cujas chaves vêm do cabeçalho, filtre e resuma linhas pelo nome da coluna e grave dicionários em CSV.
  4. Reconheça as exceções que o Python lança, leia um traceback para encontrar a causa, capture os erros esperados e mantenha um programa em execução ou interrompa-o com uma mensagem clara em vez de deixá-lo encerrar inesperadamente.
    • Reconheça exceções comuns e leia um traceback
      Saiba o que é uma exceção, leia um traceback de baixo para cima e nomeie os tipos comuns de exceção e suas causas típicas.
    • Capture exceções com try e except
      Escreva blocos try e except que capturem os erros específicos esperados, forneçam uma mensagem útil ao usuário e permitam que erros inesperados continuem aparecendo.
    • Use else e finally e acompanhe exceções entre funções
      Complete uma instrução try com else e finally, preveja a ordem em que seus blocos são executados e decida em qual função uma exceção deve ser tratada.
    • Trate falhas de forma controlada em programas que usam arquivos e dados
      Combine o tratamento de arquivos e exceções para que arquivos ausentes ou bloqueados e dados inválidos resultem em mensagens claras, linhas ignoradas ou uma interrupção controlada em vez de um encerramento inesperado.
  5. Use raise para impedir que uma função continue com uma entrada inválida, escolha tipos e mensagens de exceção adequados e repasse erros ou transforme-os em erros mais claros.
    • Lance exceções para rejeitar entradas inválidas
      Use a instrução raise para sinalizar que uma função recebeu um valor com o qual não consegue trabalhar e deixe o código chamador decidir como responder.
    • Relance e encadeie exceções e defina exceções personalizadas
      Repasse uma exceção depois de reagir a ela, transforme um erro de baixo nível em um erro mais claro e crie seus próprios tipos de exceção para problemas específicos do seu programa.

Guia de estudo de Arquivos e exceções em Python

5 capítulos

1

Leia e grave arquivos de texto

Arquivos permitem que um programa mantenha informações entre execuções e trabalhe com dados coletados em outros lugares. A leitura traz texto para a memória; a gravação salva resultados para a próxima execução ou para outra pessoa. Você escolherá um método de leitura, controlará exatamente o que é gravado e usará indentação para manter arquivos abertos apenas enquanto forem necessários. Em seguida, exemplos linha por linha combinam operações com strings, decisões e contadores para transformar texto bruto em resultados úteis.

1.1 Leitura de texto em um programa

Um arquivo de texto mantém informações depois que um programa para. O Python usa um objeto de arquivo, retornado por open(), para trabalhar com essas informações. A abertura conecta o programa ao arquivo; uma operação de leitura recupera seu texto.

Escolha o que ler

O modo padrão é "r", para leitura. Um nome sem caminho é procurado no diretório de trabalho atual. Se ele estiver ausente nesse diretório, open() lança FileNotFoundError.

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

Suponha que o arquivo tenha três linhas, “apple”, “banana” e “cherry”, todas com terminadores de linha. text é 'apple\nbanana\ncherry\n'. A sequência de escape \n representa um caractere de nova linha. Uma última linha também pode terminar sem esse caractere.

OperaçãoResultadoÚtil quando
f.read()Todo o texto restante como uma stringVocê precisa de um arquivo pequeno por inteiro
f.readline()A próxima linha como uma stringVocê precisa de uma linha agora
f.readlines()Todas as linhas restantes como uma listaVocê precisa reutilizar as linhas
for line in f:Uma linha por passagemVocê pode processar as linhas em ordem

readline() retorna '' no fim do arquivo. Uma linha em branco que tem um terminador de linha retorna '\n', então uma linha em branco e o fim do arquivo são diferentes.

Acompanhe a posição

A leitura avança a posição no arquivo. Depois que f.read() consome o arquivo, outra chamada retorna ''; um laço sobre o mesmo objeto não tem mais nada a percorrer. Abra o arquivo novamente para recomeçar ou mantenha o texto ou as linhas necessárias em uma variável. read() e readlines() carregam o restante do arquivo na memória. Percorrer diretamente o arquivo permite processar um arquivo grande uma linha por vez.

As linhas mantêm seus caracteres de nova linha. print(line) acrescenta seu próprio caractere de nova linha, o que pode deixar linhas em branco extras na tela. Use print(line, end="") para manter o espaçamento original ou remova o terminador de linha antes de imprimir. line.rstrip("\n") remove caracteres de nova linha do fim; line.strip() também remove espaços das duas extremidades.

Transforme texto em números

Mesmo os dígitos chegam como strings. Este arquivo contém as notas “72”, “85” e “90”:

scores = []
with open("scores.txt", encoding="utf-8") as f:
    for line in f:
        scores.append(int(line))
total = sum(scores)
print(total, round(total / len(scores), 2))

A lista é [72, 85, 90], então o programa imprime 247 82.33. int() aceita espaços e caracteres de nova linha ao redor dos dígitos. Uma string vazia ou uma palavra como "forty" lança ValueError.

Leia caracteres com a codificação correta

Uma codificação associa caracteres a bytes armazenados. UTF-8 pode representar caracteres como “é” e emojis. Use encoding="utf-8" explicitamente para arquivos UTF-8. O Python 3.15 ativa o modo UTF-8 por padrão; instalações anteriores podem usar uma codificação local. Uma codificação incorreta pode produzir texto corrompido ou UnicodeDecodeError. Informar a codificação explicitamente não converte em UTF-8 um arquivo salvo em outra codificação.

O bloco with fecha o arquivo quando termina. Um arquivo fechado não pode ser lido: outra chamada a f.read() lança ValueError.

Principais conclusões

  • open() retorna um objeto de arquivo; a leitura recupera texto a partir de sua posição atual.
  • Escolha uma string, uma lista de linhas ou um laço linha por linha de acordo com a tarefa.
  • O fim do arquivo retorna ''; uma linha em branco pode retornar '\n'.
  • Converta texto numérico com int() ou float() antes de calcular.
  • Use a codificação correspondente ao arquivo e feche-o quando terminar.

1.2 Arquivos que fecham quando o bloco termina

Um arquivo aberto usa recursos do sistema operacional. O texto que está sendo gravado também pode esperar em um buffer de memória antes de chegar ao arquivo. Fechar o arquivo libera os recursos e descarrega a saída do buffer. Uma instrução with organiza essa liberação em um ponto claro do código.

Leia dentro do bloco e use o resultado depois
with open("notes.txt", encoding="utf-8") as f:
    text = f.read()
print(len(text))

Os dois-pontos iniciam o bloco. A linha indentada é executada enquanto f está aberto. Quando a execução chega ao print() sem indentação, o arquivo já foi fechado, mas text continua sendo uma string comum. O nome f ainda se refere ao objeto de arquivo; f.closed agora é True.

O mesmo padrão funciona para uma lista:

with open("fruit.txt", encoding="utf-8") as f:
    lines = f.readlines()
for line in lines:
    print(line.strip().upper())

O laço usa dados já lidos em lines. Mover f.readlines() para fora do bloco tentaria ler um arquivo fechado e lançaria ValueError.

Liberação de recursos quando a execução muda de direção

Considere uma função que retorna a primeira linha:

def first_line(path):
    with open(path, encoding="utf-8") as f:
        return f.readline().rstrip("\n")

O valor de retorno é preparado dentro do bloco. O Python então sai do bloco e fecha o arquivo antes que o código chamador receba esse valor. O arquivo também fecha quando uma exceção sai do bloco. Uma chamada manual a f.close() colocada depois de uma instrução que falha nunca seria alcançada.

Objetos de arquivo oferecem esse comportamento porque são gerenciadores de contexto: objetos que organizam a preparação e a liberação de recursos em torno de um bloco with. Você pode usar esse comportamento sem escrever um gerenciador de contexto por conta própria.

Abra uma entrada e uma saída juntas
with open("in.txt", encoding="utf-8") as src, open("out.txt", "w", encoding="utf-8") as dst:
    for line in src:
        dst.write(line.upper())

Cada linha de entrada é convertida em maiúsculas e gravada na saída. Ambos os arquivos fecham quando o bloco termina. Se a segunda abertura falhar, o primeiro arquivo, já aberto por with, será fechado quando o Python sair da instrução.

Liberação de recursos e recuperação têm funções diferentes

with não captura erros de arquivo. Se open() não conseguir encontrar notes.txt, ele lançará FileNotFoundError antes da execução do corpo. Se a conversão de uma linha com int() falhar dentro do corpo, o arquivo fechará e a exceção continuará se propagando. É necessária uma cláusula except correspondente para recuperar-se do erro ou mostrar uma mensagem.

A ausência de dois-pontos no fim da linha de with causa SyntaxError.

Principais conclusões

  • with fecha um arquivo aberto na saída normal, no retorno e na saída por exceção.
  • Strings e listas armazenadas continuam utilizáveis depois que o arquivo fecha.
  • A indentação marca o período em que o arquivo fica aberto.
  • A liberação de recursos não captura uma exceção; a recuperação exige try e except.

1.3 Criação, substituição e acréscimo de texto

A gravação começa com uma escolha sobre os dados existentes. O modo controla se o Python lê, substitui, amplia ou cria um arquivo. Faça essa escolha antes de chamar open(), pois a substituição acontece imediatamente.

Escolha o modo
ModoArquivo existenteArquivo ausente
"r"Abre para leituraLança FileNotFoundError
"w"Esvazia o conteúdo e abre para gravaçãoCria o arquivo
"a"Acrescenta a saída ao fimCria o arquivo
"x"Lança FileExistsErrorCria o arquivo

Abrir a única cópia de dados importantes com "w" destrói seu conteúdo anterior mesmo que nenhum write() venha depois. Use um arquivo de saída separado enquanto aprende a transformar dados. "x" é útil quando a substituição de um arquivo existente deve ser recusada.

Acrescentar "b", como em "rb", seleciona o modo binário para bytes brutos. Modos de texto trabalham com strings e uma codificação; modos binários não recebem um argumento encoding.

Decida onde as linhas terminam
with open("todo.txt", "w", encoding="utf-8") as f:
    f.write("buy milk\n")
    f.write("call Sam\n")

O arquivo tem as duas linhas “buy milk” e “call Sam”. write() acrescenta exatamente a string fornecida, sem separador automático. Sem os caracteres de nova linha, o arquivo conteria "buy milkcall Sam" em uma linha.

write() retorna o número de caracteres gravados. Por exemplo, f.write("Ana,92\n") retorna 7. Essa é uma contagem de caracteres, não necessariamente o número de bytes codificados no disco. Ele aceita uma string; f.write(42) lança TypeError. Converta um número primeiro, por exemplo, com f.write(f"{score}\n").

Compare os recursos de saída

print() pode gravar em um arquivo:

with open("total.txt", "w", encoding="utf-8") as f:
    print("Total:", 247, file=f)

O texto de saída é "Total: 247\n". print() converte seus argumentos, separa-os com espaços e acrescenta um caractere de nova linha ao fim por padrão.

writelines() recebe uma sequência de strings, mas não insere terminadores de linha. f.writelines(["a", "b"]) grava "ab". Para obter um item por linha, inclua um caractere de nova linha em cada string ou junte as strings com "\n" e acrescente um caractere de nova linha ao fim.

Mantenha as execuções anteriores
with open("log.txt", "a", encoding="utf-8") as f:
    f.write("Program started\n")

Começando sem um arquivo, duas execuções produzem duas linhas. Com "w", cada execução substituiria o registro anterior. O modo de acréscimo não fornece um caractere de nova linha ausente: se o texto existente terminar no meio de uma linha, o novo texto começa imediatamente depois dele.

Para um relatório, percorra pares como [("Ana", 92), ("Ben", 78)] e grave f"{name}: {score}\n". A formatação acontece antes da gravação, então f"{82.333:.1f}" produz o texto "82.3". Em seguida, with fecha a saída e descarrega o texto do buffer no fim do bloco.

Principais conclusões

  • "w" esvazia o conteúdo de um arquivo existente assim que o abre.
  • "a" acrescenta ao fim; "x" recusa substituir um arquivo existente.
  • write() recebe uma string e não acrescenta um caractere de nova linha.
  • print(..., file=f) converte valores e acrescenta um caractere de nova linha por padrão.
  • writelines() grava strings consecutivamente sem acrescentar separadores.
  • Modos binários leem ou gravam bytes e não recebem argumento de codificação.

1.4 Como encontrar e salvar linhas úteis

Muitas tarefas com arquivos consistem em um laço com uma decisão dentro dele. Leia uma linha, remova o espaçamento indesejado, decida se ela interessa e atualize um resultado. Manter essas etapas separadas facilita a verificação do programa.

Examine um arquivo de registro

Suponha que server.log contenha estes registros, com uma linha em branco antes do último:

2026-03-01 08:14 INFO Server started
2026-03-01 08:20 ERROR Disk almost full
2026-03-01 09:02 INFO User login: maya
2026-03-01 09:15 WARNING Slow response
2026-03-01 10:40 ERROR Database timeout

2026-03-01 11:05 INFO Backup finished

Cada registro que não está em branco tem data, horário, nível e mensagem. Divida apenas três vezes para manter a mensagem junta:

errors = 0
with open("server.log", encoding="utf-8") as f:
    for line in f:
        line = line.strip()
        if not line:
            continue
        parts = line.split(maxsplit=3)
        if parts[2] == "ERROR":
            errors += 1
            print(parts[3])
print(errors, "errors")

Para o segundo registro, parts[2] é "ERROR" e parts[3] é "Disk almost full". Essa mensagem é impressa e o contador sobe para 1. O erro posterior faz o contador subir para 2. O programa imprime as duas mensagens e depois “2 errors”.

Verifique a parte desejada
TesteO que ele pergunta
line.startswith("From:")A linha começa com este texto?
"ERROR" in lineEste texto ocorre em alguma posição?
line.find("ERROR")Onde está sua primeira ocorrência ou o resultado é -1?
parts[2] == "ERROR"Este campo específico é exatamente o nível de erro?

Buscar em qualquer posição também encontraria “INFO No ERRORS today”. Verificar o campo de nível responde à pergunta sobre o registro com mais precisão.

Após strip(), uma linha em branco é ""; dividi-la produz []. A indexação de parts[2] lançaria então IndexError. O continue pula essa linha antes de qualquer indexação. Um registro que não está em branco, mas está incompleto, também precisa de uma verificação de comprimento quando esses registros são possíveis.

Conte categorias ou grave um arquivo filtrado

Um dicionário mantém uma contagem por nível. Para cada registro, defina level = parts[2] e depois counts[level] = counts.get(level, 0) + 1. Para o registro acima, as contagens são {'INFO': 3, 'ERROR': 2, 'WARNING': 1}. O valor padrão 0 inicia uma categoria na primeira vez que ela aparece.

Para salvar registros correspondentes, abra um destino separado na mesma instrução with e grave uma linha quando seu nível corresponder ao desejado. Mantenha a line original se o espaçamento for importante; se gravar o texto limpo, coloque seu caractere de nova linha de volta. Nunca abra a própria origem com "w": seu conteúdo seria esvaziado antes do início da leitura.

Veja caracteres invisíveis

print(repr(line)) torna visíveis os espaços e caracteres de nova linha no fim, por exemplo, 'Disk full \n'. strip() remove ambos, enquanto rstrip("\n") mantém os espaços. A leitura normal em modo texto traduz os terminadores de linha reconhecidos do Windows, Unix e Mac antigo para "\n". Uma última linha sem terminador permanece sem ele. Um nome de arquivo obtido por input("File name: ").strip() permite que o mesmo laço funcione com diferentes arquivos de entrada.

Principais conclusões

  • Limpe, selecione, processe e apresente o resultado em etapas separadas.
  • Pule linhas em branco antes de indexar campos divididos.
  • Verifique o campo desejado quando uma busca na linha inteira puder encontrar correspondências indesejadas.
  • Use um dicionário para manter um contador por categoria.
  • Grave a saída filtrada em outro arquivo.
  • repr() revela espaços e caracteres de nova linha ocultos na impressão normal.
2

Encontre arquivos usando caminhos

Um nome de arquivo correto é apenas parte de uma localização. A pasta onde um programa começa afeta os caminhos relativos e pode ser diferente da pasta que contém o script. Você acompanhará caminhos em uma árvore de pastas, evitará sequências de escape em strings do Windows e construirá localizações com pathlib. Essas habilidades ajudam a explicar erros de arquivo ausente e permitem que o mesmo projeto encontre seus dados e prepare pastas de saída em diferentes computadores.

2.1 Onde o Python procura um arquivo

Um caminho descreve uma localização em uma árvore de pastas. Ele pode começar na raiz dessa árvore ou no diretório de trabalho atual do programa. Um arquivo pode existir no computador e ainda assim estar ausente na localização solicitada pelo programa.

Leia um caminho a partir de seu ponto de partida
TipoExemploPonto de partida
Absoluto, macOS ou Linux/Users/maya/data/notes.txtA raiz /
Absoluto, WindowsC:/Users/Maya/data/notes.txtA raiz da unidade C
Relativodata/notes.txtDiretório de trabalho atual

Suponha que uma pasta chamada project contenha uma pasta scripts e uma pasta data. Você executa python scripts/report.py enquanto trabalha em project. Abrir "data/notes.txt" procura dentro de project/data, embora o script esteja em project/scripts.

Se, em vez disso, você iniciar o mesmo script enquanto trabalha em project/scripts, esse caminho relativo apontará para dentro de project/scripts/data. O script não mudou de lugar; o ponto de partida mudou.

from pathlib import Path
print(Path.cwd())

Isso imprime o diretório de trabalho atual. os.getcwd() após import os fornece a mesma informação como uma string. Editores e ferramentas de execução podem escolher um diretório de trabalho, então verifique-o quando a localização não estiver clara.

Percorra pastas

Em um caminho relativo, . significa a pasta atual e .. significa sua pasta pai. A partir de project/scripts, ../data/notes.txt sobe até project e depois entra em data. Acrescentar .. sem verificar a pasta de partida pode levar um programa à localização errada.

Um caminho absoluto é útil para identificar uma localização exata, mas um caminho como C:/Users/Maya/Desktop/data.csv vincula o código compartilhado às pastas de uma pessoa. Use um caminho relativo com um ponto de partida claro ou construa o caminho a partir da própria pasta do script quando for lá que os dados estão.

Mantenha intactas as barras invertidas do Windows

O Windows geralmente exibe barras invertidas entre pastas. Em uma string comum do Python, uma barra invertida inicia uma sequência de escape: \n torna-se um caractere de nova linha e \t, uma tabulação. Portanto, o literal "C:\new\table.txt" não contém o caminho pretendido.

Estas formas preservam o caminho pretendido:

raw = r"C:\new\table.txt"
escaped = "C:\\new\\table.txt"
forward = "C:/new/table.txt"

O Python no Windows aceita barras comuns. Uma string bruta impede que barras invertidas se tornem sequências de escape, mas não pode terminar com uma única barra invertida. Por exemplo, r"C:\data\" é uma sintaxe inválida.

Verifique o nome e a pasta

Procure diferenças na escrita e extensões ocultas: um arquivo exibido como “notes.txt” pode, na verdade, se chamar “notes.txt.txt”. Letras maiúsculas e minúsculas também importam. O Linux geralmente distingue Data.csv de data.csv; as configurações usuais do Windows e do macOS não fazem essa distinção. Usar exatamente as mesmas maiúsculas e minúsculas mantém um projeto utilizável em diferentes sistemas.

Principais conclusões

  • Caminhos relativos partem do diretório de trabalho atual.
  • O diretório de trabalho pode ser diferente da pasta do script.
  • . permanece na pasta atual; .. passa para sua pasta pai.
  • Use strings brutas, barras invertidas duplicadas ou barras comuns para caminhos do Windows.
  • Verifique nomes exatos, extensões e letras maiúsculas e minúsculas quando um arquivo estiver ausente.

2.2 Construção de caminhos com pathlib

O módulo padrão pathlib dá a um caminho seu próprio objeto. Um Path permite juntar nomes de pastas, inspecionar um nome de arquivo e realizar tarefas comuns com arquivos sem construir manualmente strings de separadores.

Junte e inspecione
from pathlib import Path
p = Path("reports") / "2026" / "sales.csv"
print(p.name)
print(p.stem)
print(p.suffix)
print(p.parent)

Os três primeiros resultados são “sales.csv”, “sales” e “.csv”. A pasta pai é o caminho reports/2026, exibido com o separador do sistema. Aqui / junta partes de um caminho; ele não divide números. O antigo os.path.join() também junta partes de caminhos em strings.

Um Path descreve uma localização mesmo antes de existir algo nela. p.exists() verifica se há algo nessa localização. p.is_file() e p.is_dir() distinguem um arquivo de um diretório. Uma verificação de existência não pode garantir uma abertura posterior: o arquivo pode desaparecer ou o acesso pode mudar entre essas operações. Trate erros de abertura quando o programa precisar se recuperar.

Leia ou grave um arquivo pequeno

open() aceita um Path diretamente. Para um arquivo pequeno, estes recursos também cuidam da abertura e do fechamento:

p = Path("greeting.txt")
p.write_text("Hello\n", encoding="utf-8")
text = p.read_text(encoding="utf-8")

text torna-se "Hello\n". write_text() substitui o conteúdo existente, assim como abrir com "w"; ele não é um recurso de acréscimo. read_text() carrega o arquivo inteiro, então use um laço sobre o arquivo quando precisar tratar um arquivo grande linha por linha.

Comece pela pasta do script

Um arquivo de dados fornecido ao lado de um script deve ser localizado a partir desse script, independentemente do diretório de trabalho:

base = Path(__file__).resolve().parent
scores_path = base / "data" / "scores.txt"
with open(scores_path, encoding="utf-8") as f:
    scores = f.readlines()

__file__ identifica o arquivo do script. resolve() torna seu caminho absoluto, e parent seleciona a pasta que o contém. Em um interpretador interativo, __file__ não está definido, então esse padrão pertence a um script.

Encontre arquivos e prepare pastas de saída
for p in sorted(Path("logs").glob("*.txt")):
    text = p.read_text(encoding="utf-8")
    print(p.name, len(text.splitlines()))

glob("*.txt") seleciona caminhos correspondentes em logs. iterdir() produz as entradas da pasta sem esse filtro por padrão de nomes. A ordenação torna a ordem previsível. splitlines() conta as linhas de texto sem tratar o terminador da última linha como uma linha vazia extra.

A gravação cria um arquivo, mas não as pastas pai ausentes. Prepare-as primeiro:

folder = Path("output") / "daily"
folder.mkdir(parents=True, exist_ok=True)
(folder / "report.txt").write_text("Ready\n", encoding="utf-8")

parents=True cria pastas ausentes acima de daily. exist_ok=True aceita um diretório que já existe. Ele não transforma um arquivo comum existente em uma pasta.

Principais conclusões

  • Path junta partes com / e funciona diretamente com open().
  • name, stem, suffix e parent mostram diferentes partes de um caminho.
  • Uma verificação de existência não garante que uma abertura posterior terá sucesso.
  • read_text() lê todo o texto; write_text() o substitui.
  • Construa caminhos a partir de Path(__file__).resolve().parent para dados relativos ao script.
  • Use glob() para encontrar correspondências e mkdir() para criar pastas ausentes.
3

Leia e grave arquivos CSV

Dados tabulares precisam de mais estrutura do que uma coleção de linhas. Um nome pode conter uma vírgula, um campo pode conter uma quebra de linha e uma quantidade ainda chega como texto. Você usará o módulo CSV para preservar esses limites, converter valores para cálculos e gravar resultados que outro programa possa ler. Colunas nomeadas tornam o processamento mais claro, enquanto verificações de cabeçalhos e da estrutura das linhas ajudam a revelar dados incompletos.

3.1 Leitura de linhas e campos CSV

Um arquivo CSV armazena uma tabela como texto. Seus registros são linhas, e seus campos são valores de colunas. Vírgulas geralmente separam os campos, mas campos delimitados por aspas podem conter vírgulas e até quebras de linha. Use o módulo csv para manter esses valores juntos.

Deixe o leitor tratar as aspas
name,quiz1,quiz2
Ana,8,9
Ben,7,6
"Lopez, Maria",10,8

A primeira linha é um cabeçalho, que contém nomes de colunas. A última linha de dados tem três campos, não quatro: a vírgula dentro do nome entre aspas faz parte do nome. Uma aspa dupla dentro de um campo delimitado por aspas é escrita duas vezes. Dividir cada linha com split(",") ignoraria essas regras e quebraria o nome em partes.

import csv
with open("grades.csv", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)
    header = next(reader)
    for row in reader:
        average = (int(row[1]) + int(row[2])) / 2
        print(row[0], average)

O leitor retorna listas de strings. next(reader) consome o cabeçalho uma vez, deixando o laço processar os dados. O programa imprime “Ana 8.5”, “Ben 6.5” e “Lopez, Maria 9.0”. Na primeira linha de dados, converter "8" e "9" dá 17 no total; em seguida, dividir por 2 dá 8,5.

Alinhe o tratamento do arquivo e a interpretação da tabela

Abra arquivos CSV com newline="" para que o próprio módulo csv trate os terminadores de linha. Isso é importante quando um campo delimitado por aspas inclui uma quebra de linha. Um registro CSV pode ocupar várias linhas físicas do arquivo, então dividir linha por linha não substitui um leitor de CSV.

O comportamento padrão do leitor mantém os valores como strings. Sem conversão, somar row[1] + row[2] junta "8" e "9" em "89". Esquecer de pular o cabeçalho faz o programa tentar converter "quiz1" e lançar ValueError.

Se um arquivo puder estar vazio, next(reader, None) consome um cabeçalho quando ele existe e retorna None caso contrário. Uma linha CSV completamente em branco se torna []. Pule essas linhas com if not row: continue antes de indexar. Uma linha que não está em branco, mas tem poucos campos, também precisa de uma verificação de comprimento; pular apenas linhas em branco não protegerá row[2] de todos os registros curtos.

Use o formato do arquivo
reader = csv.reader(f, delimiter=";", skipinitialspace=True)

Isso seleciona pontos e vírgulas como separadores e remove espaços imediatamente após eles. Escolha o separador que o arquivo realmente usa; mudar o separador não converte vírgulas decimais em pontos decimais. float("2,50") ainda lança ValueError.

Alguns arquivos exportados de planilhas começam com uma marca de ordem de bytes UTF-8. Ler um desses arquivos com encoding="utf-8" pode deixar "\ufeff" no início do primeiro campo, transformando o cabeçalho "name" em "\ufeffname". Para esse formato, encoding="utf-8-sig" remove o marcador; ele também pode ler arquivos UTF-8 sem o marcador.

Principais conclusões

  • Um registro CSV pode conter vírgulas ou quebras de linha em campos delimitados por aspas.
  • Use csv.reader em vez de uma simples divisão por vírgulas para respeitar as regras de aspas.
  • Abra arquivos CSV com newline="" e uma codificação correspondente.
  • O leitor padrão retorna strings; pule o cabeçalho antes da conversão numérica.
  • Verifique linhas vazias ou curtas antes de acessar os campos.
  • Selecione o delimitador correto e trate a marca de ordem de bytes quando presente.

3.2 Gravação de linhas de tabela como CSV

Um gravador de CSV transforma valores em campos corretamente separados e delimitados por aspas. Forneça a ele linhas como sequências de valores e deixe que ele cuide da pontuação. Isso evita uma saída que parece correta até que um nome ou uma mensagem contenha uma vírgula.

Grave um cabeçalho e dados
import csv
with open("summary.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["name", "average"])
    writer.writerow(["Ana", 8.5])
    writer.writerow(["Lopez, Maria", 9.0])

O arquivo tem as linhas name,average, Ana,8.5 e "Lopez, Maria",9.0. O gravador converte números em texto. Ele coloca o nome com vírgula entre aspas e duplica qualquer aspa dupla dentro de um campo delimitado por aspas. None torna-se um campo vazio, então ler o arquivo novamente não recupera None automaticamente.

writerow() recebe uma linha. writerows() recebe uma sequência de linhas, como [["Ana", 8.5], ["Ben", 6.5]]. Passar "Ana" diretamente a writerow() fornece três caracteres, produzindo A,n,a. Use ["Ana"] para uma linha com um campo.

Dê ao CSV o controle dos terminadores de linha

Use newline="" ao abrir a saída. O gravador padrão termina registros com "\r\n". Permitir também a tradução de caracteres de nova linha do modo texto pode acrescentar um retorno de carro extra no Windows, produzindo linhas em branco indesejadas em alguns leitores. O argumento newline impede essa segunda camada de tradução.

Transforme um arquivo em outro
with open("grades.csv", newline="", encoding="utf-8") as src, open("summary.csv", "w", newline="", encoding="utf-8") as dst:
    reader = csv.reader(src)
    writer = csv.writer(dst)
    next(reader)
    writer.writerow(["name", "average"])
    for row in reader:
        average = (int(row[1]) + int(row[2])) / 2
        writer.writerow([row[0], round(average, 2)])

Para as linhas de notas “Ana,8,9”, “Ben,7,6” e "Lopez, Maria",10,8, as médias são 8,5, 6,5 e 9,0. O leitor remove a delimitação por aspas do CSV do valor do campo de entrada; o gravador acrescenta novamente as aspas necessárias na saída. round() controla o valor numérico gravado, embora não obrigue a exibição de duas casas decimais. Use um formato como f"{average:.2f}" quando quiser exatamente duas casas.

Acrescente sem repetir o cabeçalho

Antes de abrir um arquivo para acréscimo, verifique se ele precisa de um cabeçalho:

from pathlib import Path
p = Path("sales.csv")
needs_header = not p.exists() or p.stat().st_size == 0
with open(p, "a", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    if needs_header:
        writer.writerow(["item", "quantity"])
    writer.writerow(["coffee", 4])

Um arquivo existente e vazio também precisa de cabeçalho. Gravar o cabeçalho em toda execução coloca nomes de colunas no meio dos dados. Esse padrão pressupõe que um único programa esteja atualizando o arquivo; uma verificação de existência não impede que outros programas o alterem.

Principais conclusões

  • Passe uma sequência de campos a writerow() e linhas a writerows().
  • O gravador converte valores e trata as aspas; None torna-se um campo vazio.
  • Use newline="" tanto para a saída quanto para a entrada de CSV.
  • Acrescente um cabeçalho apenas quando o arquivo for novo ou estiver vazio.

3.3 Uso de nomes de colunas em código CSV

Código baseado em posição, como row[2], depende da ordem das colunas. Um leitor baseado em dicionários permite nomear o valor necessário. Um dicionário associa chaves a valores; aqui, o cabeçalho fornece as chaves e cada registro de dados fornece seus valores.

Leia campos pelo nome
import csv
with open("inventory.csv", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    rows = list(reader)

Para o cabeçalho product,stock,price e a linha notebook,12,2.50, o primeiro dicionário é {'product': 'notebook', 'stock': '12', 'price': '2.50'}. reader.fieldnames fornece os nomes do cabeçalho. O cabeçalho é consumido automaticamente; chamar next(reader) pularia o primeiro registro de dados.

Use row["stock"] para selecionar o estoque, mesmo que as colunas sejam reordenadas. Converta-o com int() para comparar quantidades. Os valores continuam sendo strings; os nomes das colunas não fornecem tipos numéricos ao leitor.

Filtre e some

Suponha que a tabela contenha estoque de 12 cadernos ao preço de 2,50, estoque de 3 canetas a 1,20, estoque de 0 grampeadores a 7,95 e estoque de 25 pastas a 0,80.

low = [r for r in rows if int(r["stock"]) < 5]
value = sum(int(r["stock"]) * float(r["price"]) for r in rows)

low contém as linhas da caneta e do grampeador. O valor é R$ 53,6: os cadernos contribuem com 30, as canetas com 3,6, os grampeadores com 0 e as pastas com 20. O filtro usa o estoque, enquanto o total usa tanto o estoque quanto o preço.

Distinga chaves ausentes de valores ausentes

Os nomes do cabeçalho devem corresponder exatamente. Name e name são chaves diferentes. Um espaço após uma vírgula pode se tornar parte de um cabeçalho; skipinitialspace=True remove espaços imediatamente após os separadores.

Um cabeçalho name,quiz1,quiz2 com os dados Ben,7 produz {'name': 'Ben', 'quiz1': '7', 'quiz2': None}. A chave existe, mas seu valor está ausente. int(None) lança TypeError. Um campo presente e vazio é "", e convertê-lo lança ValueError. Uma chave ausente do cabeçalho causa KeyError na consulta.

Com os dados Cara,1,2,3, campos extras são reunidos como None: ['3']; os campos nomeados ainda contêm "Cara", "1" e "2". Verifique a estrutura de uma linha quando totais precisos dependerem de todos os campos.

Grave colunas selecionadas
with open("reorder.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["product", "stock"])
    writer.writeheader()
    for r in low:
        writer.writerow({"product": r["product"], "stock": r["stock"]})

fieldnames define a ordem da saída, independentemente da ordem do dicionário. Chaves ausentes do dicionário tornam-se campos vazios. Chaves extras lançam ValueError por padrão: passar um dicionário de estoque que contém price a esse gravador de duas colunas falha. Crie o dicionário menor como mostrado ou escolha extrasaction="ignore" quando descartar campos extras for intencional.

Principais conclusões

  • DictReader consome o cabeçalho e retorna dicionários com valores em strings.
  • Os nomes do cabeçalho devem corresponder exatamente às chaves de consulta.
  • Um campo ausente recebe None por padrão; um campo presente e vazio é "".
  • Campos extras são colocados sob a chave None por padrão.
  • DictWriter precisa de fieldnames para definir a ordem das colunas.
  • Chaves de saída ausentes tornam-se campos vazios; chaves inesperadas lançam ValueError por padrão.
4

Trate erros com try e except

Nomes de arquivos podem estar errados, o acesso pode ser negado e uma coluna numérica pode conter uma palavra. Uma exceção marca o ponto em que a execução normal não pode continuar. Você lerá relatórios de erros, capturará problemas esperados e manterá as ações em caso de sucesso separadas da liberação de recursos. Acompanhar erros pelas chamadas de função ajuda a colocar a recuperação onde seja possível tomar uma decisão útil, como tentar uma leitura novamente ou informar um registro rejeitado.

4.1 Como entender um relatório de erro

Uma exceção é um objeto que sinaliza um problema durante a execução. Lançá-la interrompe a execução normal. Se nenhum tratador lidar com ela, o Python encerra o programa com um traceback, um relatório das chamadas que levaram ao erro.

Comece pela parte inferior
def average(values):
    return sum(values) / len(values)

def report():
    scores = []
    print(average(scores))

report()

O traceback termina com ZeroDivisionError: division by zero. Comece por ali: o tipo indica a espécie de problema e a mensagem fornece detalhes. A entrada imediatamente acima aponta para a divisão em average(). Entradas anteriores mostram a chamada de report() e a chamada original a report(). A lista está vazia, então seu comprimento é 0. A linha indicada como falha é onde o problema aparece; a atribuição anterior da lista vazia explica como ele surgiu.

Escolha o tipo correspondente
TipoCausa típica
ValueErrorint("3.5"): uma string com um valor inaceitável
TypeErrorlen(5): uma operação sobre o tipo errado de objeto
ZeroDivisionErrorDivisão por zero
IndexErrorLeitura de uma posição de lista que não existe
KeyErrorConsulta de uma chave de dicionário ausente
NameErrorUso de um nome não definido
AttributeErrorSolicitação de um atributo que o objeto não possui

int("abc") recebe um tipo de entrada permitido, uma string, mas não consegue interpretar esse valor como um inteiro. Já "5" + 3 mistura tipos incompatíveis para adição. Uma string que contém dígitos continua sendo uma string.

Operações com arquivos têm tipos mais específicos: FileNotFoundError para um caminho ausente, PermissionError para acesso negado e FileExistsError para a criação de um arquivo existente com "x". Abrir um diretório como um arquivo comum pode lançar IsADirectoryError. Decodificar bytes com uma codificação incompatível pode lançar UnicodeDecodeError.

Entenda a árvore de família

As classes de exceção formam uma hierarquia. Um tratador para uma classe pai pode capturar suas classes filhas:

  • OSError é a classe pai de erros comuns do sistema de arquivos, incluindo FileNotFoundError e PermissionError.
  • LookupError é a classe pai de IndexError e KeyError.
  • ArithmeticError é a classe pai de ZeroDivisionError.
  • UnicodeDecodeError está abaixo de ValueError.

Esses ramos descendem de Exception, que descende de BaseException. Já KeyboardInterrupt e SystemExit descendem diretamente de BaseException. Essa distinção permite que except Exception deixe passar a interrupção pelo usuário e a saída do programa.

Separe problemas de sintaxe, execução e lógica

A ausência de dois-pontos ou de um parêntese de fechamento pode impedir o Python de analisar um script. O SyntaxError resultante ocorre antes da execução do script, então um try nesse mesmo script não pode capturá-lo. Uma exceção em tempo de execução ocorre enquanto código válido é executado. Um erro de lógica produz uma resposta errada sem necessariamente lançar uma exceção, como dividir um total pela contagem errada.

Principais conclusões

  • Leia primeiro o tipo de exceção e a mensagem na parte inferior de um traceback.
  • Use as entradas de chamadas para rastrear o valor que causou a falha até sua origem.
  • ValueError diz respeito a um valor inaceitável; TypeError diz respeito a um tipo inadequado.
  • Um tratador de exceção para uma classe pai também captura as classes filhas.
  • Erros de sintaxe, de execução e de lógica acontecem de maneiras diferentes.

4.2 Captura de um problema onde ele pode ser tratado

Uma instrução try executa código que pode falhar e oferece um caminho de recuperação para exceções selecionadas. O tratador deve corresponder ao problema que o programa espera e ao qual sabe responder.

Acompanhe o fluxo
while True:
    try:
        age = int(input("Age: "))
        break
    except ValueError:
        print("Please enter a whole number, like 34.")
print("Next year you will be", age + 1)

Digitar “twenty” faz int() lançar ValueError. O Python ignora o restante do try, incluindo break, e executa o tratador correspondente. O laço então pergunta novamente. Digitar “34” permite que o try prossiga até break, então o programa sai do laço e imprime “Next year you will be 35”.

Um tratador não retoma a execução na instrução que falhou. A execução prossegue depois da instrução try, a menos que o próprio tratador altere esse fluxo. Se nenhum tratador corresponder, a exceção se propaga.

Trate falhas diferentes de maneiras diferentes
try:
    result = int(a) / int(b)
except ValueError:
    print("Both values must be whole numbers.")
except ZeroDivisionError:
    print("The second value cannot be 0.")

Uma conversão inválida e um divisor zero precisam de mensagens diferentes. Se a resposta tiver de ser idêntica, agrupe os tipos em uma tupla: except (ValueError, ZeroDivisionError):. Os parênteses funcionam em todo o Python 3. O Python 3.14 também permite uma lista sem parênteses quando não há uma parte as; a forma de tupla continua clara em todas as versões.

O Python verifica as cláusulas de cima para baixo e executa a primeira correspondente. Coloque FileNotFoundError antes de seu tipo pai OSError se um arquivo ausente precisar de uma resposta especial. Inverter a ordem torna o tratador especial inalcançável.

Use a mensagem sem ocultar outros defeitos
try:
    quantity = int(text)
except ValueError as err:
    print("Cannot read quantity:", err)

err é o objeto de exceção; imprimi-lo mostra sua mensagem. type(err).__name__ fornece o nome de sua classe. O Python apaga a associação de err no tratador quando ele termina, então copie sua mensagem para outra variável dentro do bloco se precisar dela depois.

Mantenha o try pequeno. Coloque cálculos posteriores fora do tratador de conversão quando suas falhas precisarem de tratamento diferente. except Exception: pode ocultar defeitos, como uma variável não definida. Um except: sem tipo é ainda mais abrangente: ele também captura KeyboardInterrupt e SystemExit.

Tente a operação, não uma imitação aproximada

Testar text.isdigit() não testa tudo o que int() aceita. "-5" e " 34" falham nesse teste, mas são convertidos com sucesso; "²" passa no teste, mas não é convertido com int(). Tentar a conversão e capturar ValueError usa as próprias regras da conversão.

Faça algo visível ou registrado ao tratar dados inválidos. Um except ValueError: pass vazio pode deixar o programa continuar com resultados ausentes e sem registro do que deu errado.

Principais conclusões

  • Uma exceção faz o código restante do try ser ignorado e executa o primeiro tratador correspondente.
  • Use tipos específicos e coloque tratadores de classes filhas antes dos tratadores de classes pai.
  • Agrupe tipos em uma tupla quando a ação de recuperação for a mesma.
  • except ... as err dá acesso à mensagem dentro do tratador.
  • Mantenha o try focado para que as mensagens descrevam a operação que realmente falhou.
  • Tente a conversão numérica diretamente quando precisar testar o que ela aceita.

4.3 Sucesso, liberação de recursos e erros entre funções

Uma instrução try pode separar a operação que pode falhar, a recuperação, as ações em caso de sucesso e a liberação de recursos. Uma exceção também pode sair de uma função e ser tratada pelo código que a chamou.

Dê às ações em caso de sucesso um bloco próprio
try:
    x = 10 / int(text)
except ValueError:
    print("not a number")
except ZeroDivisionError:
    print("zero")
else:
    print("result", x)
finally:
    print("done")

Com text = "4", o programa imprime “result 2.5” e “done”. Com "abc", imprime “not a number” e “done”; com "0", imprime “zero” e “done”.

else é executado quando o try termina normalmente, sem uma exceção. Ele não é executado depois que um tratador se recupera de um erro. Também é ignorado quando return, break ou continue faz a execução sair do try antes do fim. Erros lançados dentro de else não são capturados pelas cláusulas except anteriores dessa instrução, então as ações em caso de sucesso não compartilham acidentalmente os tratadores da operação que pode falhar.

Libere recursos em todos os caminhos de saída

finally é executado quando o controle sai da instrução: após o sucesso, após uma exceção tratada e antes que uma exceção não tratada continue se propagando. Ele também é executado antes que um retorno pendente seja concluído.

def label():
    try:
        return "from try"
    finally:
        print("finally ran")

value = label()
print(value)

Isso imprime “finally ran” e depois “from try”. O retorno aguardou enquanto os recursos eram liberados. Para arquivos, with já fornece o comportamento de fechamento, então geralmente elimina a necessidade de um fechamento manual em finally.

Não coloque uma saída como return, break ou continue em finally. Sair do bloco de liberação dessa maneira pode descartar uma exceção pendente ou substituir um retorno. O Python 3.14 e versões posteriores emitem um SyntaxWarning para esse padrão. Use esse bloco apenas para liberar recursos.

Acompanhe uma exceção até o código chamador
def read_scores(path):
    with open(path, encoding="utf-8") as f:
        return [int(line) for line in f]

try:
    scores = read_scores("scores.txt")
except FileNotFoundError:
    print("The score file is missing.")

Se a abertura falhar, read_scores() não tem tratador, então FileNotFoundError se propaga até a chamada dentro do try externo. O código chamador o trata e imprime a mensagem. Se uma linha não for um inteiro, um ValueError segue o mesmo caminho, mas o tratador de arquivo ausente não corresponde a ele.

Escolha o nível que pode dar uma resposta útil

Uma função de leitura pode saber como obter dados, mas não se um arquivo ausente deve provocar uma nova tentativa, uma tarefa ignorada ou uma interrupção controlada. Deixar a exceção chegar ao código chamador que interage com o usuário mantém essa escolha ali. Capturá-la cedo demais e retornar uma lista vazia pode ocultar a diferença entre um arquivo vazio e uma leitura que falhou.

Principais conclusões

  • else é executado somente após a conclusão normal do corpo do try.
  • finally é executado antes que o controle saia da instrução, inclusive em um retorno ou uma exceção não tratada.
  • Uma exceção em else está fora do alcance dos tratadores anteriores dessa instrução.
  • Evite saídas de finally que possam descartar erros ou retornos pendentes.
  • Exceções não tratadas propagam-se pelas chamadas até um tratador externo correspondente.

4.4 Recuperação de erros de arquivo e de linha

Um programa trata uma falha de forma controlada quando responde a um problema de maneira controlada e útil. Ele pode perguntar novamente, informar uma linha ignorada ou parar com uma mensagem clara. Escolha essa resposta de acordo com o uso do resultado.

Tente novamente quando um arquivo estiver ausente
while True:
    name = input("File name: ").strip()
    try:
        with open(name, encoding="utf-8") as f:
            text = f.read()
    except FileNotFoundError:
        print(f"No file named '{name}'. Please try again.")
    else:
        break
print(len(text.splitlines()), "lines")

Uma abertura que falha ignora a atribuição e chega ao tratador. O laço pergunta novamente. Uma leitura bem-sucedida chega a else, interrompe o laço e deixa text disponível para a contagem final. O arquivo é fechado por with em qualquer saída de um bloco em que se tenha entrado.

Para problemas diferentes de arquivo, use FileNotFoundError, depois PermissionError e depois um tratador geral de OSError se outros erros do sistema de arquivos precisarem de uma resposta. As cláusulas específicas devem vir primeiro. Decodificar bytes inválidos é um problema diferente; uma mensagem sobre um caminho ausente não o descreveria.

Trate cada linha de dados separadamente

Para um resumo rápido de vendas, suponha que as linhas CSV após o cabeçalho sejam coffee,4, tea,two, muffin,3, cookie, e juice,5.

import csv
total = 0
skipped = 0
with open("sales.csv", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)
    next(reader, None)
    for row in reader:
        try:
            if len(row) != 2:
                raise ValueError("expected two fields")
            quantity = int(row[1])
        except ValueError as err:
            skipped += 1
            print(f"sales.csv, ending line {reader.line_num}: {err}")
        else:
            total += quantity
print("Total:", total, "Skipped:", skipped)

As quantidades válidas totalizam 12. A palavra “two” e a quantidade vazia são rejeitadas, então a contagem de linhas ignoradas é 2. A verificação da linha também transforma uma quantidade inesperada de campos em um erro de dados informado antes da indexação. Colocar try dentro do laço permite que o próximo registro seja processado após a falha de um registro; colocar o laço dentro de um único try faria a execução sair do laço na primeira falha.

Informe as localizações com precisão

Para os cinco registros de uma linha cada, os valores inválidos terminam nas linhas 3 e 5 do arquivo. enumerate(reader, start=2) corresponderia a esses números de linha aqui, mas uma quebra de linha dentro de aspas faz um registro CSV ocupar mais de uma linha. reader.line_num informa quantas linhas físicas o leitor consumiu. Chamá-la de linha final mantém as mensagens precisas para registros de várias linhas.

Decida se um resultado parcial é aceitável

Uma contagem exploratória rápida pode permitir que linhas sejam ignoradas e informadas. Um total financeiro ou de notas pode precisar de todos os registros: pare e peça dados corrigidos em vez de apresentar um total parcial como completo. Informe o arquivo, a localização e o problema para que ele possa ser corrigido.

Após import sys, sys.exit("Could not open sales.csv") grava a mensagem na saída de erros e encerra com código de saída 1. Ele lança SystemExit, que except Exception não captura. Mantenha os tratadores específicos para que um erro de programação não relacionado não seja identificado incorretamente como um problema de arquivo.

Principais conclusões

  • Escolha tentar novamente, pular ou parar de acordo com a tarefa.
  • Coloque a recuperação por registro dentro do laço para continuar após uma linha inválida.
  • Informe os registros ignorados e identifique claramente resultados parciais.
  • Números de registros CSV podem ser diferentes dos números de linhas físicas.
  • sys.exit(message) encerra com uma mensagem de erro e código de saída 1.
  • Use tratadores específicos para que a mensagem corresponda ao problema real.
5

Lance suas próprias exceções

Funções precisam de uma maneira clara de informar entradas que não conseguem tratar. Lançar uma exceção impede que uma operação que falhou produza um resultado enganoso e permite que o código chamador escolha uma resposta. Você escolherá tipos e mensagens significativos, repassará um erro existente e preservará sua causa ao transformá-lo. Um breve padrão de classe personalizada fornece ao programa um tipo de erro próprio quando o código chamador precisa distinguir um problema de outro.

5.1 Rejeição de entradas com raise

Uma função deve sinalizar quando não consegue produzir um resultado válido. raise inicia uma exceção nesse ponto, impedindo que o caminho inválido continue como se a operação tivesse dado certo.

Verifique antes de calcular
def withdraw(balance, amount):
    if amount <= 0:
        raise ValueError(f"amount must be positive, got {amount}")
    if amount > balance:
        raise ValueError(f"amount {amount} is more than the balance {balance}")
    return balance - amount

withdraw(100, 30) retorna 70. withdraw(100, 150) lança um erro sobre o saldo; withdraw(100, -5) lança um erro sobre um valor que não é positivo. Nenhuma das chamadas que falham chega à subtração.

Uma exceção lançada segue as mesmas regras de tratamento de um erro embutido. Se um tratador correspondente dentro da função a capturar, a execução poderá continuar ali. Caso contrário, a exceção sai da função e chega ao código chamador. Se nenhum tratador for encontrado, o Python apresenta um traceback.

Deixe o código chamador escolher a resposta
balance = 100
amount = 150
try:
    balance = withdraw(balance, amount)
except ValueError as err:
    print(f"Cannot withdraw: {err}")

A função informa por que não consegue realizar o saque. O código chamador decide exibir uma mensagem. Como a chamada de função falha antes de retornar, a atribuição não substitui o saldo anterior por um resultado. Outro código chamador poderia pedir um valor menor ou cancelar uma transação sem alterar a função.

Imprimir um aviso dentro da função e retornar None pode fazer o código chamador levar um valor inválido para um cálculo posterior. Lançar uma exceção mantém a falha ligada à sua causa e oferece ao código chamador um caminho de erro distinto.

Escolha um tipo significativo
ProblemaTipo adequado
Tipo correto de entrada, valor inaceitávelValueError
Tipo de objeto errado para a operaçãoTypeError

Um valor numérico negativo é inaceitável. Uma lista fornecida onde um número é necessário tem um tipo inadequado. O tipo de exceção faz parte do comportamento da função: o código chamador o usa para selecionar tratadores. Não escolha um tipo apenas por ser familiar.

Escreva uma mensagem útil

Uma mensagem deve indicar o que era esperado e o que chegou. f"age must be between 0 and 130, got {age}" indica uma correção. Uma mensagem como “erro” não fornece detalhes úteis. Mantenha a mensagem relacionada à operação que falhou; o código que interage com o usuário pode acrescentar o contexto mais amplo.

raise ValueError("amount must be positive") cria uma exceção com uma mensagem. raise ValueError também é válido e cria uma exceção sem mensagem. Uma string simples não é uma exceção: raise "error" lança TypeError porque objetos lançados devem derivar de BaseException.

Principais conclusões

  • Lance uma exceção no ponto em que uma função não pode continuar corretamente.
  • Use ValueError para um valor inaceitável e TypeError para um tipo inadequado.
  • Inclua a entrada esperada e o valor recebido em uma mensagem útil.
  • Deixe o código chamador decidir como responder à operação que falhou.

5.2 Repasse e nomeação de exceções

Às vezes, uma função percebe um erro, mas não consegue concluir seu tratamento. Ela pode precisar repassar o mesmo erro, transformá-lo em um erro mais útil ou dar a um problema específico do programa seu próprio tipo de exceção.

Relance o erro atual
def read_text(path):
    try:
        with open(path, encoding="utf-8") as f:
            return f.read()
    except FileNotFoundError:
        print(f"Missing: {path}")
        raise

O raise sem argumento dentro do tratador relança a exceção atual. Apenas imprimir uma mensagem terminaria o tratador e faria a função retornar None; relançar torna a falha de leitura visível ao código chamador. Um raise sem argumento precisa de uma exceção ativa para relançar.

Transforme o erro preservando a causa
def read_price(row):
    try:
        text = row["price"]
    except KeyError as err:
        raise ValueError("row has no 'price' column") from err
    return float(text)

Uma chave ausente torna-se um ValueError com uma mensagem sobre a linha. from err registra o KeyError original como sua causa direta. O traceback mostra o erro original, a ligação entre eles e o novo erro. O código chamador pode tratar o tipo transformado, enquanto a causa de nível inferior continua disponível para depuração.

Esse tratador limita-se à consulta. Um valor presente como "free" falha depois em float(text) com seu próprio ValueError; ele não é informado incorretamente como uma coluna ausente.

Defina um tipo distinto
class InsufficientFundsError(ValueError):
    pass

Esse padrão cria uma classe de exceção personalizada. O nome termina em Error por convenção. O nome entre parênteses é sua classe pai, então essa classe é um tipo de ValueError.

def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFundsError(
            f"balance {balance}, requested {amount}"
        )
    return balance - amount

try:
    withdraw(100, 150)
except InsufficientFundsError as err:
    print("Not enough money:", err)

O programa imprime “Not enough money: balance 100, requested 150”. O código chamador pode distinguir saldo insuficiente de outro valor inválido. Se um tratador de ValueError aparecesse antes desse tratador específico, o tipo pai o capturaria primeiro.

Escolha a classe pai para o tratamento desejado

Derivar de ValueError permite que tanto um tratador específico quanto um tratador mais amplo de erro de valor capturem o tipo personalizado. Derivar diretamente de Exception cria um ramo separado de erros comuns, então except ValueError não o capturaria. Um tipo personalizado é útil quando o código chamador precisa de uma resposta distinta; um tipo embutido claro e uma mensagem são suficientes quando isso não é necessário.

Principais conclusões

  • raise sem argumento em um tratador repassa a exceção atual.
  • raise NewError(...) from err registra o erro original como causa direta.
  • Uma exceção personalizada fornece ao código chamador um tipo de problema distinto.
  • A classe pai determina quais tratadores mais amplos podem capturar o erro personalizado.
  • Coloque um tratador personalizado específico antes do tratador de sua classe pai.

Exercícios resolvidos de Arquivos e exceções em Python

5 Lições Interativas

1

Transforme um arquivo de texto em um relatório filtrado

13 passos
Leia linhas, escolha modos de arquivo e salve registros selecionados, deixando claro quando os arquivos estão abertos.
  1. 1
    IntroduçãoLeia, decida, salve

    Um registro de suporte contém um evento por linha. Você quer um novo arquivo contendo apenas os eventos que precisam de atenção. Essa tarefa combina leitura, verificações de strings e gravação.

    Primeiro acompanhe como um arquivo fornece texto. Depois construa o filtro em pequenas etapas, mantendo a entrada separada da saída e deixando que with feche os dois arquivos quando o processamento terminar.

  2. 2
    ExplicaçãoUm arquivo fornece strings

    Suponha que events.txt contenha "INFO Ready\nERROR Queue full\n". Abri-lo cria um objeto de arquivo, não uma cópia de seu texto.

    f.readline() retorna "INFO Ready\n". Uma segunda chamada retorna "ERROR Queue full\n". Uma terceira retorna "" porque o arquivo chegou ao fim. O caractere de nova linha permanece na linha retornada; texto numérico também permaneceria como texto até ser explicitamente convertido.

  3. 3
    DesafioEscolha um método de leitura

    Um arquivo de registro pode ser muito maior que a memória disponível. Você só precisa inspecionar cada linha uma vez. Como deve lê-lo e por quê?

    ---reveal---

    Percorra diretamente o arquivo aberto com for line in f:. Ele fornece uma linha por vez sem exigir antes uma string ou lista com o arquivo inteiro. Chamar read() ou readlines() carregaria o conteúdo restante na memória.

  4. 4
    ExemploMantenha a leitura dentro do bloco
    with open("events.txt", encoding="utf-8") as f:
        first = f.readline()
    print(first.rstrip("\n"))
    

    A leitura acontece enquanto o arquivo está aberto. Sair do bloco indentado o fecha; a impressão posterior usa a string salva. Por isso, uma operação sobre first pode acontecer depois, enquanto outra chamada a f.readline() não pode.

  5. 5
    DesafioPreveja a liberação de recursos após um erro

    Dentro desse bloco de arquivo, suponha que int("oops") lance ValueError. O código ao redor não tem tratador. O arquivo permanece aberto e with oculta o erro?

    ---reveal---

    O arquivo fecha quando a execução sai do bloco em que entrou. O erro ainda se propaga e produz um traceback se nada o capturar. A liberação automática de recursos protege o período de uso do arquivo; um tratador except seria necessário para a recuperação.

  6. 6
    ExplicaçãoEscolha o comportamento da saída

    O relatório filtrado deve substituir um relatório anterior, então abra um caminho de saída diferente com "w". Esse modo esvazia imediatamente o conteúdo de um arquivo existente.

    Para um histórico de atividades que mantenha execuções anteriores, use "a". Se um relatório existente precisar ser protegido contra substituição, use "x" e trate FileExistsError. A criação do arquivo ainda exige que as pastas que o contêm existam.

  7. 7
    ExemploGrave exatamente uma linha

    Para gravar uma linha selecionada, mantenha seu terminador original:

    dst.write(line)
    

    Se você a tiver limpado com strip(), coloque o terminador de volta:

    dst.write(cleaned + "\n")
    

    write() não acrescenta separador. print(cleaned, file=dst) é outra forma de acrescentar um caractere de nova linha, enquanto writelines() ainda espera que as strings fornecidas contenham os terminadores necessários.

  8. 8
    DesafioPreveja duas execuções

    Começando sem um arquivo, um programa é executado duas vezes. Em cada execução, ele abre "runs.txt" em modo de acréscimo e chama f.write("OK"). Que texto é salvo?

    ---reveal---

    O arquivo contém "OKOK". O modo de acréscimo mantém a primeira execução, mas nem o modo nem write() acrescentam um caractere de nova linha. Gravar "OK\n" produziria uma linha por execução. Abrir em "w" deixaria apenas o "OK" mais recente.

  9. 9
    ExemploLimpe antes de selecionar

    Nosso arquivo de registro usa a primeira palavra como nível. Comece cada passagem com:

    cleaned = line.strip()
    if not cleaned:
        continue
    level = cleaned.split(maxsplit=1)[0]
    

    A verificação de linha vazia impede a indexação de uma lista vazia. Manter a line original separadamente permite que a saída preserve seu espaçamento. Apenas a cópia limpa é usada para identificar o nível.

  10. 10
    DesafioVerifique a parte correta

    O arquivo de registro inclui “INFO ERROR counter reset” e “ERROR Queue full”. Qual teste de nível salva apenas o segundo registro?

    ---reveal---

    Teste level == "ERROR" depois de extrair a primeira palavra. Buscar "ERROR" em qualquer posição também salvaria o registro informativo porque a palavra ocorre em sua mensagem. O formato informa onde encontrar a categoria que você está selecionando.

  11. 11
    ExemploMonte o filtro
    count = 0
    with open("events.txt", encoding="utf-8") as src, open("urgent.txt", "w", encoding="utf-8") as dst:
        for line in src:
            cleaned = line.strip()
            if not cleaned:
                continue
            if cleaned.split(maxsplit=1)[0] == "ERROR":
                dst.write(line)
                count += 1
    print(count, "saved")
    

    O contador muda apenas quando um registro é gravado. Os dois arquivos fecham antes que a contagem seja impressa.

  12. 12
    DesafioDiagnostique a perda da origem

    Alguém muda o nome da saída para "events.txt", mantendo "w". Por que agora o filtro corre o risco de não salvar nada, embora a origem tenha sido aberta primeiro?

    ---reveal---

    A segunda abertura esvazia o mesmo arquivo antes que o laço o leia. O primeiro objeto de arquivo não salvou uma cópia separada do texto anterior. Volte a usar um caminho de saída diferente para que a transformação não possa apagar sua entrada na abertura.

  13. 13
    RecapitulaçãoRastreie uma tarefa com arquivos antes de executá-la

    Para uma transformação de arquivo, acompanhe quatro decisões: de onde vem a entrada, quanto texto é lido de uma vez, o que seleciona um registro e o que a abertura da saída faz com dados existentes.

    Depois verifique os limites dos blocos. Operações com arquivos precisam de objetos de arquivo abertos; strings, listas e totais salvos podem ser usados depois que os arquivos fecham.

2

Localize dados do projeto a partir de qualquer pasta de execução

9 passos
Rastreie caminhos relativos, construa caminhos relativos ao script e prepare pastas com pathlib.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoEncontre a pasta de partida
  2. 2
    ExemploRastreie uma execução
  3. 3
    DesafioMude a pasta de execução
  4. 4
    DicaInspecione antes de alterar o caminho
  5. 5
    ExemploConstrua a partir do script
  6. 6
    ExplicaçãoPrepare um destino
  7. 7
    DesafioInspecione um nome e encontre correspondências
  8. 8
    DesafioVerifique uma correção proposta
  9. 9
    RecapitulaçãoSepare localização de disponibilidade
3

Leia uma tabela e grave um relatório com colunas nomeadas

13 passos
Interprete CSV com campos entre aspas, converta campos numéricos e exporte colunas selecionadas em uma ordem controlada.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoPreserve a estrutura da tabela
  2. 2
    ExemploLeia um registro com aspas
  3. 3
    ExemploAbra e converta
  4. 4
    DesafioReconheça uma linha curta
  5. 5
    ExemploGrave valores como campos
  6. 6
    DesafioMantenha um campo inteiro
  7. 7
    ExplicaçãoUse o cabeçalho como chaves
  8. 8
    ExemploFiltre por estoque
  9. 9
    DesafioDistinga ausente de vazio
  10. 10
    ExemploExporte colunas selecionadas
  11. 11
    DesafioAcrescente um lote posterior
  12. 12
    DicaAjuste separadores e codificações
  13. 13
    RecapitulaçãoVerifique a estrutura e o significado
4

Acompanhe um erro de uma linha inválida até uma resposta útil

15 passos
Leia um traceback, selecione tratadores e distinga uma nova tentativa de leitura de arquivo da recuperação dentro de um laço de linhas.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoEscolha o que pode se recuperar
  2. 2
    ExemploComece pelo tipo de exceção
  3. 3
    DesafioReconheça uma falha diferente
  4. 4
    ExemploCapture apenas o erro de conversão esperado
  5. 5
    DesafioOrdene tratadores relacionados
  6. 6
    ExplicaçãoDê funções separadas ao sucesso e à liberação de recursos
  7. 7
    DesafioRastreie um erro sem correspondência
  8. 8
    ConexãoDeixe o código chamador decidir
  9. 9
    ExemploMantenha a recuperação dentro do laço de registros
  10. 10
    ExemploAcompanhe três registros
  11. 11
    DesafioMude o limite do laço
  12. 12
    DicaIdentifique a localização corretamente
  13. 13
    DesafioEscolha um resultado completo
  14. 14
    ExemploEncerre com um código de erro
  15. 15
    RecapitulaçãoColoque cada resposta no nível adequado
5

Projete o comportamento de erro de uma função

10 passos
Valide uma solicitação, lance erros úteis e preserve distinções e causas para o código chamador.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoDê à falha um caminho claro
  2. 2
    ExemploRejeite solicitações inválidas
  3. 3
    DesafioRastreie uma atribuição que falhou
  4. 4
    ExplicaçãoAssocie o tipo ao problema
  5. 5
    ExemploNomeie uma falta específica de lugares
  6. 6
    DesafioMantenha a resposta específica alcançável
  7. 7
    ExemploReaja e repasse o erro
  8. 8
    ExemploTransforme uma falha de nível inferior
  9. 9
    DesafioEscolha a relação adequada
  10. 10
    RecapitulaçãoMantenha o erro significativo para o código chamador

Questões de Arquivos e exceções em Python

50 Questões de Prática em 5 conjuntos

Conjunto 1: Trabalho com arquivos e caminhos de recuperação10 Questões de Prática

Questão 1 de 10

Um arquivo contém apenas “bad”. O que é impresso?

try:
    with open("one.txt", encoding="utf-8") as f:
        value = int(f.readline())
except ValueError:
    print(f.closed)
  1. False
  2. True
  3. Um traceback de NameError.
  4. Um traceback de FileNotFoundError.
Mostrar respostaOcultar resposta
Resposta: B
A conversão lança uma exceção dentro de um bloco with em que a execução entrou, então sair desse bloco fecha o arquivo antes da execução do tratador externo. O valor impresso é True. O tratador fornece a recuperação; with libera os recursos e não faz a conversão que falhou ser retomada.

Questão 2 de 10

Um novo arquivo é gravado com f.writelines(["red", "blue\n"]) e depois aberto mais uma vez em modo de acréscimo para gravar "green\n". Que texto ele contém?
  1. "redblue\ngreen\n"
  2. "red\nblue\ngreen\n"
  3. "green\n"
  4. "redbluegreen\n"
Mostrar respostaOcultar resposta
Resposta: A
writelines() não acrescenta separadores, então a primeira operação grava "redblue\n". O modo de acréscimo mantém esse texto e acrescenta "green\n". O caractere de nova linha ausente após “red” não é fornecido pelo nome do método, e o modo de acréscimo não substitui a saída anterior.

Questão 3 de 10

As pastas results e results/daily estão ausentes. O que deve ser executado antes de gravar com Path("results/daily/run.txt").write_text("ok", encoding="utf-8")?
  1. Path("results/daily").mkdir(exist_ok=True)
  2. Path("results/daily/run.txt").mkdir(parents=True)
  3. Path("results/daily").exists()
  4. Path("results/daily").mkdir(parents=True, exist_ok=True)
Mostrar respostaOcultar resposta
Resposta: D
Crie o diretório que conterá o arquivo com parents=True para que sua pasta pai ausente também seja criada. exist_ok=True também permite execuções posteriores quando o diretório já existe. Sem parents=True, criar daily falha porque results está ausente; a gravação não cria nenhum dos dois diretórios.

Questão 4 de 10

Um programa de acréscimo grava um cabeçalho apenas quando not p.exists(). O caminho existe, mas tem zero bytes. Qual condição também fornece a esse arquivo o cabeçalho necessário?
  1. p.exists() and p.stat().st_size > 0
  2. not p.exists() and p.stat().st_size == 0
  3. not p.exists() or p.stat().st_size == 0
  4. p.exists()
Mostrar respostaOcultar resposta
Resposta: C
Um cabeçalho é necessário para um arquivo ausente ou para um existente e vazio, então una essas condições com or. A verificação de tamanho identifica o caso de zero bytes que a verificação de existência, sozinha, não identifica. Usar and deixaria de identificar um arquivo existente e vazio e poderia tentar inspecionar um caminho ausente.

Questão 5 de 10

Um DictReader padrão tem o cabeçalho name,first,second e lê Inez,5. Qual valor é armazenado sob "second" e o que acontece quando ele é passado a int()?
  1. None; lança TypeError.
  2. ""; lança ValueError.
  3. "5"; retorna 5.
  4. Sem chave; lança KeyError.
Mostrar respostaOcultar resposta
Resposta: A
Um campo ausente é preenchido com None por padrão, então a chave do cabeçalho existe, mas int(None) lança TypeError. Um campo presente e vazio conteria "" e lançaria ValueError. Um cabeçalho define a chave mesmo quando esse registro tem poucos valores.

Questão 6 de 10

Qual exceção a consulta ao dicionário {"east": 4}["west"] lança?
  1. IndexError
  2. ValueError
  3. KeyError
  4. NameError
Mostrar respostaOcultar resposta
Resposta: C
O dicionário não tem uma chave chamada "west", então sua consulta lança KeyError. IndexError diz respeito a uma posição inválida em uma sequência, como um índice de lista. O dicionário e a string são objetos válidos; é a chave solicitada que está ausente.

Questão 7 de 10

O que o código chamador recebe e o que é impresso primeiro?

def choose():
    try:
        return 11
    finally:
        print("leaving")
x = choose()
  1. Recebe None; “leaving” é impresso primeiro.
  2. Recebe 11; nada é impresso.
  3. Recebe “leaving”; 11 é impresso primeiro.
  4. Recebe 11; “leaving” é impresso primeiro.
Mostrar respostaOcultar resposta
Resposta: D
O valor de retorno 11 é preparado, depois finally imprime “leaving” antes que a função conclua seu retorno. Imprimir durante a liberação de recursos não substitui esse valor de retorno pendente. Um return dentro de finally alteraria esse comportamento, mas esse bloco contém apenas print().

Questão 8 de 10

Um resumo CSV deve informar linhas numéricas malformadas e continuar até os registros posteriores. Onde deve ficar o try/except ValueError da conversão?
  1. Ao redor de todo o laço, fora de seu corpo.
  2. Dentro do laço, ao redor da conversão de cada linha.
  3. Depois do laço, ao redor da impressão final.
  4. Apenas ao redor da chamada inicial a open().
Mostrar respostaOcultar resposta
Resposta: B
Um tratador interno lida com uma linha e devolve o controle ao laço para o próximo registro. Um tratador fora de todo o laço é executado depois que a exceção já saiu dele, então as linhas posteriores não são percorridas. A abertura e a impressão final não protegem a conversão durante a iteração.

Questão 9 de 10

Dado class LimitError(ValueError): pass, um LimitError é lançado. O que acontece se except ValueError: aparecer antes de except LimitError:?
  1. Nenhuma das cláusulas corresponde ao tipo personalizado.
  2. Apenas o tratador de ValueError é executado.
  3. Ambos os tratadores são executados na ordem escrita.
  4. Apenas o tratador de LimitError é executado.
Mostrar respostaOcultar resposta
Resposta: B
LimitError herda de ValueError, então o tratador da classe pai corresponde primeiro e é o único executado. Tipos personalizados seguem as mesmas regras de primeira correspondência dos tipos embutidos. Coloque o tratador personalizado primeiro quando sua resposta precisar ser diferente da resposta a outros erros de valor.

Questão 10 de 10

Depois de remover os caracteres das extremidades e pular linhas em branco, um analisador define parts = line.split(maxsplit=2). Os registros devem ter data, nível e mensagem, mas alguns contêm apenas uma data. Qual verificação deve vir antes de parts[1] e parts[2]?
  1. len(parts) == 3
  2. line.endswith("\n")
  3. len(line) > 3
  4. " " in parts[0]
Mostrar respostaOcultar resposta
Resposta: A
Os acessos precisam de três campos, e maxsplit=2 produz no máximo três, então len(parts) == 3 verifica a estrutura necessária. Pular linhas em branco não protege contra um registro não vazio com um único campo. A contagem de caracteres também não determina o número de campos.
Conjunto 2: Diagnóstico de dados incompletos e tratadores enganosos10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

No fim do arquivo, o que f.readline() retorna?
  1. None
  2. "\n"
  3. []
  4. ""
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

data.txt contém três registros. Um programa o abre com "r", depois abre o mesmo caminho com "w" e só então começa a ler pelo primeiro objeto de arquivo. Por que isso traz risco de perda da entrada?
  1. O modo de leitura remove o caractere de nova linha final antes da gravação.
  2. O primeiro objeto de arquivo passa automaticamente ao modo de acréscimo.
  3. A abertura para gravação esvazia o conteúdo do arquivo antes da leitura.
  4. O objeto de gravação copia cada linha antes de substituí-la.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

p.exists() retorna True, mas o arquivo é removido antes de open(p, encoding="utf-8"). O que um programa robusto ainda precisa ter nessa abertura?
  1. Um tratador para arquivo ausente com uma resposta útil.
  2. Uma segunda verificação de existência que garanta acesso.
  3. O modo de gravação para recriar a entrada esperada vazia.
  4. Uma operação de limpeza para remover o nome ausente.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

Um script deve ler data/menu.txt ao lado de sua própria localização, independentemente da pasta de execução. Qual expressão constrói esse caminho no script?
  1. Path.cwd() / "data" / "menu.txt"
  2. Path(__file__).resolve().parent / "data" / "menu.txt"
  3. Path(__file__) / "data" / "menu.txt"
  4. Path("data") / "menu.txt"
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Um CSV em UTF-8 começa com uma marca de ordem de bytes. Com encoding="utf-8", sua primeira chave de cabeçalho é "\ufeffcode". Qual alteração na abertura remove o marcador preservando o texto UTF-8?
  1. Use encoding="utf-8-sig" para o arquivo.
  2. Use newline="\n" em vez de newline="".
  3. Use delimiter=";" em vez de uma vírgula.
  4. Use skipinitialspace=True para todos os campos.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Uma linha é {"title": "Map", "stock": "4", "cost": "3.50"}. Um DictWriter padrão tem fieldnames=["title", "stock"]. O que acontece quando ele grava a linha inteira sem alterações?
  1. Ele grava dois campos e descarta cost.
  2. Ele acrescenta cost ao cabeçalho automaticamente.
  3. Ele lança ValueError pela chave extra.
  4. Ele grava cost como um terceiro campo sem nome.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Um laço de entrada captura ValueError de int(text). Esse tratador imprime missing_name, que nunca foi definido. O que acontece com o novo NameError?
  1. O mesmo except ValueError tenta tratá-lo novamente.
  2. Ele se transforma no erro de conversão original.
  3. O tratador o suprime e termina normalmente.
  4. Ele se propaga, a menos que um tratador externo o capture.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Depois de um cabeçalho, um registro CSV começa com "North na linha física 2 e termina com Hall",7 na linha 3. Depois de lê-lo, qual localização reader.line_num informa?
  1. 1
  2. 3
  3. 2
  4. 7
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Uma função auxiliar imprime “bad size” e retorna None para um tamanho negativo. Seu código chamador multiplica imediatamente o resultado por 4. Por que lançar ValueError na validação melhoraria esse caminho de falha?
  1. Retorna um valor numérico padrão para cálculos posteriores.
  2. Garante que o código chamador tente novamente a solicitação.
  3. Sinaliza o tamanho inválido antes de um cálculo posterior falhar.
  4. Informa um erro de conversão de tipo antes da validação.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Depois de capturar um KeyError como err, um tratador executa raise ValueError("missing unit column") from err. O que o código chamador recebe e qual causa é preservada?
  1. Um KeyError causado pelo ValueError.
  2. Um ValueError causado pelo KeyError.
  3. Um ValueError sem uma causa anterior.
  4. Um retorno normal com as duas strings de mensagem.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 3: Combinação de processamento de arquivos com comportamento de erro confiável10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Um programa entra em with open("source.txt", encoding="utf-8") as src, open("new.txt", "x", encoding="utf-8") as dst:. A origem abre, mas new.txt existe. O que acontece com src e o corpo?
  1. src fecha; FileExistsError impede a execução do corpo.
  2. src fica aberto; o corpo é executado sem destino.
  3. src fecha; o corpo acrescenta dados ao destino.
  4. src fica aberto; o corpo substitui o destino.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Um arquivo de registro tem "10:00 INFO ERROR resolved", "10:01 ERROR Disk slow" e "10:02 ERROR Disk full". O segundo campo é o nível. Depois de filtrar pelo nível de erro, quantos registros são salvos?
  1. 1
  2. 0
  3. 3
  4. 2
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Um processo começa em /srv/course, executa tools/read.py e abre "../shared/items.txt". Qual caminho ele solicita?
  1. /srv/course/shared/items.txt
  2. /srv/shared/items.txt
  3. /srv/course/tools/shared/items.txt
  4. /shared/items.txt
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

Um gravador CSV padrão recebe ["Vale, East", None, 3]. Qual registro é produzido, desconsiderando seu terminador de linha final?
  1. Vale, East,None,3
  2. "Vale, East",,3
  3. "Vale, East",None,3
  4. Vale,East,,3
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Um script divide 30 pelo número 5 escrito diretamente no código quando a contagem pretendida é 6. Ele imprime 6.0 sem nenhuma exceção. Que tipo de problema é esse?
  1. Um erro de sintaxe causado pelo divisor.
  2. Um TypeError na divisão numérica.
  3. Um erro de lógica na contagem escolhida.
  4. Um ZeroDivisionError no total.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

O que é impresso antes de o erro se propagar?

try:
    n = int("2")
except ValueError:
    print("bad input")
else:
    print("ready")
    result = 9 / 0
finally:
    print("cleanup")
  1. “bad input”, depois “cleanup”
  2. Apenas “ready”
  3. Apenas “cleanup”
  4. “ready”, depois “cleanup”
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Um analisador deve aceitar toda string que int() aceita, incluindo espaços no início e um sinal. Por que tentar int(text) em try em vez de exigir primeiro text.isdigit()?
  1. As operações aceitam conjuntos diferentes de strings.
  2. isdigit() converte strings com sinal em inteiros.
  3. int() aceita toda string que contém um dígito.
  4. Uma instrução try remove espaços da entrada.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Uma ferramenta executa sys.exit("Required file unavailable") dentro de código coberto por except Exception:. O que acontece?
  1. O tratador recebe ValueError e tenta novamente.
  2. A ferramenta retorna a mensagem como um valor normal.
  3. SystemExit passa pelo tratador; o código de saída é 1.
  4. O tratador recebe SystemExit e continua.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Um resumo CSV inicializa total = 0 e skipped = 0. Um tratador interno pula uma linha se ela tiver menos de dois campos ou se int(row[1]) falhar. Ele soma ao total os valores válidos convertidos. Para as linhas ["lamp", "8"], ["desk"], ["chair", "bad"] e ["shelf", "5"], qual par final é informado?
  1. total = 8, skipped = 1
  2. total = 13, skipped = 2
  3. total = 13, skipped = 1
  4. total = 8, skipped = 2
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Dado class ImportDataError(Exception): pass, um código chamador captura apenas ValueError. O que acontece quando sua função auxiliar lança ImportDataError?
  1. Ele se propaga porque sua classe está fora do ramo de ValueError.
  2. Ele é capturado porque ValueError também descende de Exception.
  3. Ele é capturado se sua mensagem descreve um valor inaceitável.
  4. Ele se torna ValueError quando a função auxiliar o repassa.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 4: Leitura de arquivos e rastreamento de pequenos programas10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Um terminal trabalha em /work/lab. Ele executa python tools/count.py, que abre "inputs/list.txt". Qual localização absoluta esse caminho relativo solicita?
  1. /work/lab/tools/inputs/list.txt
  2. /work/inputs/list.txt
  3. /inputs/list.txt
  4. /work/lab/inputs/list.txt
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Para p = Path("exports/week/report.csv"), qual é o valor de p.stem?
  1. ".csv"
  2. "report"
  3. "report.csv"
  4. "exports/week"
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Usando o csv.reader padrão, qual lista é lida do registro "River, West",6,8?
  1. ['River, West', '6', '8']
  2. ['River, West', 6, 8]
  3. ['\"River', ' West\"', '6', '8']
  4. ['River', 'West', '6', '8']
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

Qual linha writer.writerow("Leo") produz com a vírgula como delimitador padrão?
  1. Leo
  2. "Leo"
  3. L,e,o
  4. L e o
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Um campo de quantidade CSV contém a string "many". Qual exceção int(row["quantity"]) lança?
  1. TypeError
  2. KeyError
  3. IndexError
  4. ValueError
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

O que é impresso?

def read_count(text):
    return 12 / int(text)
try:
    result = read_count("0")
    print("read")
except ValueError:
    print("bad text")
except ZeroDivisionError:
    print("zero")
print("end")
  1. “read”, depois “end”
  2. “bad text”, depois “end”
  3. “zero”, depois “end”
  4. “zero”, depois “read”
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Uma função aceita uma contagem inteira de páginas, mas não pode processar uma contagem abaixo de 1. Para a entrada -2, qual exceção e mensagem são adequadas?
  1. TypeError("pages must be positive, got -2")
  2. ValueError("pages must be positive, got -2")
  3. IndexError("pages must be positive, got -2")
  4. NameError("pages must be positive, got -2")
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Um arquivo contém "oak\npine". Imediatamente após abri-lo para leitura, o que f.readline() retorna?
  1. "oak"
  2. ["oak\n", "pine"]
  3. "oak\n"
  4. "oak\npine"
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

O bloco termina normalmente. O que é impresso?

with open("memo.txt", encoding="utf-8") as f:
    text = f.read()
print(f.closed)
  1. False
  2. True
  3. None
  4. text
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Um programa deve acrescentar uma mensagem de execução a um arquivo de registro, mantendo todas as mensagens anteriores. Qual modo de arquivo de texto deve usar?
  1. "a"
  2. "w"
  3. "r"
  4. "x"
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 5: Escolha de métodos e tratamento de falhas esperadas10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

O que é impresso?

def reserve(n):
    if n <= 0:
        raise ValueError("positive count required")
    return n * 2
result = 7
try:
    result = reserve(0)
except ValueError:
    print(result)
  1. 7
  2. 0
  3. None
  4. 14
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Um arquivo de registro tem as linhas "09:10 INFO ERROR count reset" e "09:12 ERROR Network down". O nível é o segundo campo separado por caracteres em branco. Qual condição seleciona apenas registros de nível de erro?
  1. "ERROR" in line
  2. line.startswith("ERROR")
  3. line.split()[2] == "ERROR"
  4. line.split()[1] == "ERROR"
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Um arquivo contém "12\n15\n". Qual par resulta de first = f.read() seguido de second = f.read() em um mesmo arquivo recém-aberto para leitura?
  1. first == "12\n15\n", second == ""
  2. first == "12\n", second == "15\n"
  3. first == "12\n15\n", second == first
  4. first == [12, 15], second == []
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

No Windows, por que o literal de string Python "C:\new\tasks.txt" pode falhar ao identificar o arquivo pretendido?
  1. O nome da unidade torna o caminho relativo à unidade.
  2. Barras invertidas funcionam apenas em caminhos relativos.
  3. As barras invertidas iniciam escapes de nova linha e tabulação.
  4. Um caminho absoluto deve começar com uma barra comum.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Um arquivo começa com city,visitors e Mesa,24. Após reader = csv.DictReader(f), o programa chama next(reader) uma vez e depois executa um laço. Por que Mesa está ausente desse laço?
  1. O leitor trata valores numéricos como nomes de campos.
  2. A chamada consumiu o primeiro registro de dados.
  3. O leitor não pode usar um cabeçalho em minúsculas.
  4. O laço pula registros sem nomes entre aspas.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

A primeira linha é label;count, mas o leitor CSV padrão retorna ["label;count"]. Qual configuração do leitor corresponde a esse arquivo?
  1. skipinitialspace=True
  2. delimiter=","
  3. quoting=csv.QUOTE_ALL
  4. delimiter=";"
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

O que é impresso?

try:
    value = 18 / int("0")
except ZeroDivisionError:
    print("zero")
else:
    print("success")
finally:
    print("closed")
  1. “success”, depois “closed”
  2. “zero”, depois “closed”
  3. “zero”, depois “success”
  4. “closed”, depois “zero”
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

É necessário um total completo de pagamentos de uma bolsa. Um CSV tem um valor inválido entre 200 registros. Por que pular esse registro e exibir o restante como o total completo é uma escolha ruim de recuperação?
  1. O total omite um pagamento necessário sem informar isso.
  2. Uma falha de conversão impede reabrir o arquivo.
  3. Pular o registro altera todos os pagamentos restantes.
  4. Um CSV não pode conter linhas válidas e inválidas.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Um FileNotFoundError ocorre em um try. O primeiro tratador é except OSError: print("file problem"), e o segundo é except FileNotFoundError: print("missing"). O que é impresso?
  1. “missing”
  2. “file problem”, depois “missing”
  3. “file problem”
  4. Nenhum tratador corresponde.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Dentro de um bloco except ValueError:, qual instrução repassa a mesma exceção ativa ao código chamador?
  1. return
  2. raise
  3. continue
  4. pass
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Travou em uma questão sua? Ajuda com Tarefas

Termos-Chave

83 Termos-Chave, cada um com sua definição

A

Acumulador
Um acumulador é uma variável atualizada durante um laço para construir um resultado, como um total ou uma contagem a partir dos registros processados.
A variável errors começa em 0 e aumenta em 1 sempre que o laço encontra um registro de nível de erro.
Arquivo de texto
Um arquivo de texto armazena caracteres como bytes codificados, geralmente organizados em linhas, e mantém seus dados depois que o programa que os gravou termina.
Um programa lê uma lista salva de notas de um arquivo de texto no início da próxima execução.
Arquivo fechado
Um arquivo fechado é um objeto de arquivo cujo acesso ao arquivo associado terminou, de modo que não é possível continuar lendo ou gravando por meio dele.
Depois que um bloco with que abriu um arquivo como f termina, f.closed é True e f.read() lança um ValueError sobre o acesso a um arquivo fechado.
Associação da exceção a um nome
A associação da exceção a um nome nomeia um objeto de erro capturado por meio de as, para que seu tipo ou mensagem possa ser inspecionado dentro desse tratador.
Em except ValueError as err:, imprimir err mostra a mensagem; a associação é apagada depois.
AttributeError
Um AttributeError sinaliza uma solicitação de um atributo ou método que um objeto não oferece.
Chamar "hi".push("!") lança AttributeError porque uma string Python não tem um método chamado push.

B

Bloco try
Um bloco try contém operações cujas exceções podem ser tratadas pelas cláusulas associadas a ele; o código restante é ignorado em caso de falha.
Uma conversão de entrada deve ficar em um bloco try pequeno para que um valor inválido possa levar à solicitação de outra entrada.
Buffer
Um buffer é uma área temporária de memória que mantém dados durante a entrada ou saída, como texto gravado que aguarda para chegar a um arquivo.
Fechar um arquivo de saída descarrega o texto do buffer, passando as gravações pendentes ao arquivo.

C

Cabeçalho
Um cabeçalho é uma linha de nomes de colunas que identifica os campos de uma tabela, geralmente colocada antes dos registros de dados em um arquivo CSV.
A linha product,stock,price nomeia colunas e não deve ser passada à conversão de inteiro como se fosse dado.
Caminho
Um caminho descreve a localização de um arquivo ou pasta por meio de nomes e separadores, começando em uma raiz ou em outro diretório conhecido.
O caminho data/notes.txt identifica um arquivo de texto dentro da pasta de dados sob o diretório de trabalho atual.
Caminho absoluto
Um caminho absoluto especifica uma localização a partir de uma raiz do sistema de arquivos, como / em sistemas semelhantes ao Unix ou a raiz de uma unidade no Windows.
A localização /Users/maya/data/notes.txt não depende do diretório de trabalho atual.
Caminho relativo
Um caminho relativo especifica uma localização a partir do diretório de trabalho atual do processo, então seu significado depende dessa pasta de partida.
Começar em project/scripts faz ../data/notes.txt apontar para a pasta de dados vizinha do projeto.
Campo
Um campo é uma parte significativa de um registro, separada ou identificada por um formato conhecido, como um nível de registro ou uma quantidade em CSV.
Em um registro com data, horário, nível e mensagem, verificar o nível evita encontrar uma palavra dentro da mensagem.
Campo ausente
Um campo ausente é um valor que falta em um registro CSV curto; um DictReader padrão preenche sua chave de cabeçalho conhecida com None.
Sob name,score, a linha Ana tem uma nota ausente; Ana, contém uma string de nota vazia.
Campo extra
Um campo extra é um valor de registro além da quantidade de campos do cabeçalho; um DictReader padrão reúne esses valores sob a chave None.
Com dois nomes de cabeçalho, uma linha de três valores mantém seus valores nomeados e armazena o valor extra em uma lista.
Caractere de nova linha
Um caractere de nova linha, escrito "\n" em uma string Python, marca uma quebra de linha; a última linha de um arquivo pode não ter terminador.
Imprimir uma linha que já termina em "\n" acrescenta outro caractere de nova linha, a menos que o terminador da impressão seja alterado.
Classe de exceção pai
Uma classe de exceção pai é a classe da qual outra classe de erro deriva, fazendo com que seus tratadores correspondam a instâncias do tipo filho.
Derivar LimitError de ValueError permite que um tratador existente de ValueError também o capture.
Cláusula else
Uma cláusula else em uma instrução try é executada quando o corpo protegido termina normalmente, sem uma exceção ou uma saída antecipada do fluxo de controle.
Uma conversão bem-sucedida pode levar a uma saída em else, enquanto um erro lançado nessa saída não é capturado pelos tratadores anteriores.
Cláusula finally
Uma cláusula finally executa a liberação de recursos quando o controle sai de uma instrução try, inclusive antes da conclusão de um retorno pendente ou da propagação de uma exceção não tratada.
Uma mensagem de encerramento em finally é impressa mesmo quando uma conversão falha e nenhum tratador associado corresponde ao tipo da exceção.
Codificação
Uma codificação é um conjunto de regras para representar caracteres como bytes, usado ao gravar texto e interpretar texto armazenado.
O texto “café” pode ficar corrompido se um leitor usar uma codificação diferente daquela usada para salvá-lo.
Código chamador
O código chamador é o código que chama uma função e recebe seu resultado retornado ou uma exceção que a função não trata.
O código chamador pode capturar um saque inválido e pedir um valor menor sem alterar a função auxiliar de cálculo.
Código de saída
Um código de saída é um resultado numérico enviado ao sistema operacional quando um programa termina, permitindo que outro programa detecte uma falha.
sys.exit("Missing input") imprime a mensagem na saída de erros e termina com código de saída 1.
Criação de diretórios
A criação de diretórios cria pastas no sistema de arquivos; mkdir(parents=True) também pode criar pastas ausentes acima da pasta solicitada.
Crie output/daily antes de gravar seu relatório, pois abrir um novo arquivo de saída não cria pastas.
Criação exclusiva
A criação exclusiva cria um arquivo novo apenas quando o caminho não está em uso e lança FileExistsError se já existir um arquivo nessa localização.
O modo "x" impede que um relatório recém-gerado substitua silenciosamente um relatório no mesmo caminho.
CSV
CSV é um formato de texto para registros tabulares formados por campos separados, com regras de aspas que permitem separadores e quebras de linha nos valores.
O registro "Lopez, Maria",10,8 tem três campos porque sua primeira vírgula está dentro de um nome entre aspas.

D

Delimitação por aspas
A delimitação por aspas envolve um campo com caracteres de aspas para que um delimitador ou uma quebra de linha dentro de seu valor seja mantido como parte desse campo.
O leitor mantém a vírgula dentro de "River, West", enquanto uma simples divisão por vírgulas quebraria esse nome.
Delimitador
Um delimitador é o caractere que separa campos em um formato de tabela, como uma vírgula, um ponto e vírgula ou uma tabulação escolhida para um leitor CSV.
Um arquivo exportado com ponto e vírgula precisa de delimiter=";" para que um leitor separe name;score em dois campos.
DictReader
Um DictReader lê registros de dados CSV como dicionários cujas chaves vêm do cabeçalho, enquanto os valores dos campos permanecem strings por padrão.
Após o cabeçalho name,score, uma linha pode ser acessada com row["score"] mesmo que as colunas sejam reordenadas.
DictWriter
Um DictWriter grava dicionários como linhas CSV usando uma sequência fornecida de nomes de campos para escolher as colunas e sua ordem.
Um gravador com fieldnames=["product", "stock"] exporta essas colunas quando recebe dicionários correspondentes.
Diretório de trabalho atual
O diretório de trabalho atual é a pasta atual do processo, usada como localização de partida quando o Python interpreta caminhos relativos.
Executar python tools/report.py a partir da raiz do projeto não muda, por si só, o diretório para a pasta tools.
Diretório pai
Um diretório pai é a pasta que contém um arquivo ou diretório; a propriedade parent de um caminho seleciona essa localização.
Para Path("reports/2026/sales.csv"), o diretório pai é o caminho reports/2026.

E

Encadeamento de exceções
O encadeamento de exceções registra um erro anterior como causa direta de uma nova exceção por meio de raise ... from err.
Uma chave de preço ausente pode se tornar um erro de linha mais claro, enquanto o traceback mantém o KeyError original como causa.
Erro de lógica
Um erro de lógica faz um programa produzir o resultado errado por causa de raciocínio ou operações incorretos, sem necessariamente lançar uma exceção.
Dividir pela contagem errada, diferente de zero, pode produzir uma média aparentemente plausível enquanto o programa é executado até o fim.
Exceção
Uma exceção é um objeto que sinaliza uma falha e interrompe a execução normal enquanto o Python procura um tratador correspondente.
Uma conversão int("many") que falha lança uma exceção antes que a próxima instrução do bloco seja executada.
Exceção personalizada
Uma exceção personalizada é uma classe de erro definida pelo programa que permite ao código chamador reconhecer um problema específico separadamente de outras falhas.
Um InsufficientFundsError pode levar a uma solicitação de valor menor, enquanto valores inválidos não relacionados recebem outra resposta.

F

Falha tratada de forma controlada
Uma falha tratada de forma controlada é uma resposta controlada a um problema, que fornece informações úteis e continua ou para de acordo com a tarefa.
Um arquivo de relatório ausente leva a uma solicitação clara de um caminho corrigido, em vez de um encerramento inesperado e confuso para o usuário.
fieldnames
A sequência fieldnames fornece os nomes de cabeçalho lidos por um DictReader ou as chaves e a ordem de saída esperadas fornecidas a um DictWriter.
Chamar writeheader() em um DictWriter imprime os nomes na ordem configurada em fieldnames.
FileExistsError
Um FileExistsError sinaliza uma operação que exige um caminho não utilizado quando algo já existe nessa localização.
Abrir um relatório existente com o modo "x" lança FileExistsError em vez de substituir seu conteúdo.
FileNotFoundError
Um FileNotFoundError sinaliza que um arquivo ou diretório solicitado não pode ser encontrado no caminho usado por uma operação do sistema de arquivos.
Uma pasta de execução incorreta pode fazer um caminho relativo de entrada lançar FileNotFoundError mesmo quando o arquivo existe em outro lugar.
Filtro de linhas
Um filtro de linhas seleciona registros por uma condição durante a leitura de um arquivo, permitindo que o programa mantenha apenas as linhas relevantes para uma tarefa.
Um filtro de registro verifica o campo de nível e grava apenas registros cujo nível é igual a "ERROR".

G

Gerenciador de contexto
Um gerenciador de contexto é um objeto que organiza o comportamento de entrada e saída em torno de um bloco with, como disponibilizar o acesso e liberar recursos.
Um objeto de arquivo atua como gerenciador de contexto para que um programa possa contar com o fechamento automático na saída do bloco.
Gravador de CSV
Um gravador de CSV transforma sequências de valores de campos em registros, convertendo valores em texto e aplicando as regras de delimitação por aspas selecionadas.
Um gravador coloca automaticamente entre aspas um nome de produto que contém vírgula quando o programa o fornece como um campo.

H

Hierarquia de exceções
Uma hierarquia de exceções é a estrutura de classes de erro em pais e filhos que determina como tratadores de tipos mais amplos encontram correspondências.
Um tratador de OSError também corresponde a FileNotFoundError, enquanto um tratador de ValueError não corresponde a KeyError.

I

IndexError
Um IndexError sinaliza uma consulta a uma sequência em uma posição que não existe, como uma indexação além do fim de uma lista.
Uma linha CSV curta com um campo lança IndexError quando um código baseado em posição tenta acessar seu segundo campo.
Instrução raise
Uma instrução raise sinaliza explicitamente uma exceção, interrompendo o fluxo normal e iniciando a busca por um tratador correspondente.
Uma função rejeita um valor que não é positivo com raise ValueError("amount must be positive") antes de calcular.
Instrução with
Uma instrução with entra em um bloco gerenciado e organiza a liberação de recursos quando o controle sai dele; para um arquivo aberto, essa liberação fecha o arquivo.
Um arquivo aberto em um bloco with fecha mesmo quando a conversão de uma linha dentro do bloco lança um erro.
IsADirectoryError
Um IsADirectoryError sinaliza uma operação que espera um arquivo, mas encontra um diretório na localização solicitada.
Em sistemas que distinguem esse caso, abrir uma pasta como um arquivo comum de entrada lança IsADirectoryError.

K

KeyboardInterrupt
Um KeyboardInterrupt sinaliza uma interrupção pelo usuário, geralmente Ctrl+C, e pertence diretamente ao ramo de BaseException, não ao de Exception.
Um except: sem tipo pode capturar Ctrl+C, enquanto except Exception: deixa a interrupção se propagar.
KeyError
Um KeyError sinaliza uma consulta a um dicionário por uma chave ausente, incluindo um nome de cabeçalho CSV que não corresponde à chave solicitada.
Consultar row["name"] falha quando o cabeçalho da tabela criou a chave "Name".

M

Marca de ordem de bytes
Uma marca de ordem de bytes é um marcador inicial de codificação incluído em alguns arquivos exportados em UTF-8, que pode aparecer no primeiro campo se for mantido.
Ler com encoding="utf-8-sig" remove o marcador inicial para que o primeiro cabeçalho corresponda ao nome pretendido.
Mensagem de erro
Uma mensagem de erro descreve uma operação que falhou ou um valor rejeitado para que quem a leia entenda o que aconteceu e o que deve corrigir.
A mensagem “pages must be positive, got -2” é mais útil que a palavra “erro” sozinha.
Modo binário
O modo binário lê e grava bytes brutos em vez de strings decodificadas e, portanto, não recebe um argumento de codificação de texto.
Um modo como "rb" indica entrada de bytes, enquanto a entrada de texto usa um modo como "r".
Modo de abertura do arquivo
Um modo de abertura do arquivo é um argumento de open() que seleciona o acesso permitido e como a abertura trata o conteúdo existente no caminho.
Um arquivo de registro de atividades usa "a" para manter mensagens anteriores, enquanto um novo relatório pode usar "w" para substituí-las.
Modo de acréscimo
O modo de acréscimo abre um arquivo para que a nova saída seja acrescentada ao fim enquanto o conteúdo existente é mantido; ele cria um arquivo ausente.
Usar "a" para mensagens de execução mantém as execuções anteriores, mas a mensagem ainda precisa de seu próprio caractere de nova linha.

N

NameError
Um NameError sinaliza o uso de um nome sem associação disponível, muitas vezes porque foi digitado incorretamente ou nunca recebeu uma atribuição.
Um tratador que imprime uma variável não definida lança NameError ao tentar informar o problema original.
Nome-base do arquivo
Um nome-base do arquivo é o componente final de um caminho sem seu último sufixo, útil para obter nomes de saída relacionados a partir de um nome de arquivo.
Para Path("logs/run.txt"), o nome-base é "run", enquanto o nome final completo é "run.txt".
Número da linha física
Um número da linha física conta as linhas reais do arquivo, que podem diferir das contagens de registros CSV quando um campo delimitado por aspas contém uma quebra de linha.
O line_num do leitor identifica a linha final consumida para um registro que ocupa duas linhas.

O

Objeto de arquivo
Um objeto de arquivo é o objeto retornado por open() que fornece a um programa métodos para ler ou gravar um arquivo aberto.
Dentro de with open("notes.txt", encoding="utf-8") as f:, o nome f refere-se ao objeto de arquivo.
Objeto Path
Um objeto Path representa um caminho em Python e fornece operações para juntar componentes, inspecionar nomes e acessar o sistema de arquivos.
A expressão Path("data") / "scores.txt" constrói uma localização que open() pode aceitar diretamente.

P

Padrão de nomes de arquivo
Um padrão de nomes de arquivo seleciona caminhos por um padrão de nome, com um curinga como * correspondendo a textos variados dentro do diretório selecionado.
Path("logs").glob("*.txt") encontra caminhos correspondentes de arquivos de texto; ordená-los fornece uma ordem previsível de processamento.
PermissionError
Um PermissionError sinaliza que o sistema operacional nega o acesso solicitado por uma operação do sistema de arquivos.
Um arquivo de entrada pode existir e ainda assim lançar PermissionError quando o programa não tem permissão para lê-lo.
Posição no arquivo
A posição no arquivo marca onde começa a próxima operação de leitura e avança conforme o programa consome texto do arquivo.
Depois que f.read() consome o conteúdo restante, uma segunda leitura retorna uma string vazia.
Propagação
A propagação leva uma exceção não tratada pelas funções chamadoras até que um tratador correspondente seja encontrado ou a execução termine.
Uma função auxiliar de leitura de arquivos pode deixar FileNotFoundError chegar ao código chamador, que sabe se deve pedir outro caminho.

R

Rastreamento de exceção
Um rastreamento de exceção informa a cadeia de chamadas que levou a uma exceção não tratada e termina com o tipo de exceção e uma mensagem explicativa.
A entrada de chamada mais abaixo pode identificar a divisão pelo comprimento de uma lista vazia como a operação que falhou.
Recuperação por registro
A recuperação por registro trata uma falha esperada de um registro dentro do laço de processamento, permitindo que registros posteriores sejam considerados quando isso for permitido.
Um resumo rápido informa uma quantidade inválida e aumenta uma contagem de registros ignorados antes de ler o próximo registro CSV.
Registro
Um registro é uma linha completa de campos CSV; geralmente ocupa uma linha física, mas pode ocupar várias linhas por meio de um campo delimitado por aspas.
Um endereço entre aspas que contém uma quebra de linha permanece um único registro quando é lido pelo módulo CSV.
Relançamento de exceção
O relançamento de exceção repassa a exceção ativa capturada com um raise sem argumento, permitindo uma ação local sem considerar a falha resolvida.
Um leitor imprime o caminho ausente e depois relança a exceção para que o código chamador decida se deve pedir outro arquivo.
Remoção de caracteres em branco das extremidades
A remoção de caracteres em branco das extremidades elimina caracteres de espaçamento do início ou do fim de um texto, incluindo espaços, tabulações e terminadores de linha.
Após line.strip(), uma linha que contém apenas espaços e um caractere de nova linha torna-se uma string vazia.

S

String bruta
Uma string bruta usa um prefixo r para que barras invertidas sejam mantidas como caracteres literais em vez de serem interpretadas como sequências de escape comuns.
O literal r"C:\new\table.txt" preserva os separadores que, de outra forma, iniciariam sequências de escape de nova linha e tabulação.
Sufixo do arquivo
Um sufixo do arquivo é a extensão final de um nome de arquivo, incluindo o ponto inicial, e está disponível pela propriedade suffix de um caminho.
O sufixo de Path("data/sales.csv") é ".csv", que um programa pode usar ao selecionar arquivos de tabela.
SystemExit
Um SystemExit sinaliza uma saída intencional do processo e é lançado por sys.exit() fora do ramo comum de Exception.
Chamar sys.exit("Missing data") lança SystemExit com uma mensagem e um código de falha que um tratador comum de Exception não captura.

T

Terminador de registro
Um terminador de registro é a sequência de caracteres que um gravador CSV acrescenta após uma linha; o gravador padrão usa "\r\n".
Abrir com newline="" permite que o gravador forneça seus próprios terminadores sem uma segunda camada de tradução.
Tratador de exceção
Um tratador de exceção é um bloco except selecionado por um tipo de exceção correspondente para executar uma resposta controlada a uma operação que falhou.
Um tratador de ValueError pode explicar que uma quantidade deve ser um número inteiro e permitir que um laço externo pergunte novamente.
Tratador específico
Um tratador específico captura uma classe restrita de exceção, permitindo que problemas esperados recebam mensagens distintas sem ocultar todos os defeitos.
Coloque FileNotFoundError antes de OSError quando um arquivo ausente precisar de uma resposta diferente da dada a outros problemas de arquivo.
Tratamento delegado
O tratamento delegado deixa uma exceção para o código chamador que tem o contexto necessário para escolher uma ação útil de recuperação para a tarefa mais ampla.
Uma função auxiliar de dados informa a falha, enquanto a parte de linha de comando decide se deve tentar novamente, pular um arquivo ou parar.
Truncamento
O truncamento esvazia o conteúdo de um arquivo existente quando ele é aberto em modo de gravação, antes que o programa forneça qualquer texto novo.
Abrir um arquivo de entrada com "w" destrói os registros anteriores mesmo que o programa nunca chegue a uma chamada de gravação.
TypeError
Um TypeError sinaliza uma operação aplicada a um tipo inadequado de objeto ou a uma combinação incompatível de tipos de objeto.
Somar "5" a 3 lança TypeError porque a adição de strings não aceita um inteiro como segundo operando.

U

UnicodeDecodeError
Um UnicodeDecodeError sinaliza que os bytes armazenados não podem ser decodificados segundo as regras selecionadas para interpretar o texto.
Um leitor de texto pode lançar UnicodeDecodeError quando a codificação real do arquivo não corresponde a encoding="utf-8".
UTF-8
UTF-8 é uma codificação de texto que pode representar qualquer caractere Unicode e usa um número variável de bytes por caractere.
Use encoding="utf-8" ao abrir um arquivo de texto salvo em UTF-8 para que suas letras acentuadas sejam decodificadas corretamente.

V

Validação
A validação verifica se uma entrada atende aos requisitos de uma operação antes que o programa a use para produzir um resultado.
Uma função de saque verifica se o valor é positivo e não ultrapassa o saldo antes de subtrair.
ValueError
Um ValueError sinaliza que uma operação recebeu um tipo de objeto permitido, mas um valor que não consegue interpretar ou aceitar para essa tarefa.
A string "3.5" é um tipo de entrada permitido para int(), mas não é uma string de inteiro e lança ValueError.

W

writerow
O método writerow grava uma sequência de valores de campos como um registro CSV, incluindo os separadores, as aspas e um terminador de registro necessários.
Use writer.writerow(["Ana", 8.5]) para um registro de dois campos, não uma string já concatenada.
writerows
O método writerows grava uma sequência de linhas, tratando cada linha fornecida como uma sequência de campos para um registro CSV.
Uma lista de listas de nomes e notas pode ser passada a writerows() para salvar vários registros em uma chamada.

Z

ZeroDivisionError
Um ZeroDivisionError sinaliza uma divisão ou operação aritmética relacionada com divisor zero, o que impede um resultado numérico.
Um cálculo de média lança ZeroDivisionError se a lista estiver vazia e seu comprimento for usado como divisor.

Sobre esta aula

Por StudeliRelatar um erro

Crie seus próprios Materiais de Estudo

Transforme suas anotações, slides e documentos em Guias de Estudo, Questões de Prática, Flashcards e mais 6 ferramentas.

Começar