Python Mensagens de Erro
Todo mundo que programa vê mensagens de erro todos os dias, inclusive quem programa há trinta anos. A diferença entre quem está começando e quem tem experiência não é errar menos: é ler a mensagem. O Python não só para o programa quando algo dá errado; ele escreve um relatório dizendo o que aconteceu, em qual linha e por qual caminho o programa chegou lá. Esse relatório se chama traceback (em inglês, "rastro de volta"). Nesta aula você aprende a ler um, peça por peça, e conhece os erros que mais aparecem.
- As partes de um traceback e por que ele se lê de baixo para cima.
- A seguir o caminho de um erro que passou por várias funções.
- O que querem dizer as marcas
^^^^e~~~^~~~embaixo da linha. - A diferença entre um
SyntaxError(o programa nem começa) e uma exceção (o programa para no meio). - Os nove erros mais comuns, com a mensagem real de cada um e o que ela quer dizer.
- As dicas
Did you mean("Você quis dizer…?") que o Python 3.14 dá.
Todos os programas desta aula rodaram no Python 3.14 da máquina da Ana (usuária ana, computador notebook), salvos na pasta pessoal dela (/home/ana) e executados com python3 arquivo.py (veja Rodando um Programa). As mensagens de erro do Python saem sempre em inglês; aqui elas aparecem exatamente como saíram, e cada uma é explicada em português.
A ideia: o bilhete do mecânico
A Ana deixou o carro na oficina porque ele parou na estrada. Quando ela volta, o mecânico entrega um bilhete:
- "A senhora girou a chave na ignição…"
- "…a ignição mandou a bomba de combustível ligar…"
- "…a bomba tentou puxar gasolina do tanque…"
- "Problema: tanque vazio."
A última linha diz o que deu errado. As de cima contam o caminho até lá: quem chamou quem. Se a Ana tem pressa, lê só a última linha. Se quer entender por que o tanque estava vazio, sobe o bilhete.
O traceback do Python é exatamente esse bilhete: a última linha é o problema; as de cima são o caminho, na ordem em que as coisas aconteceram. Por isso a regra de ouro desta aula é: leia de baixo para cima.
1. O primeiro traceback
Comece por um programa bem curto, que divide por zero de propósito:
print("Começou")
print(10 / 0)
print("Fim")
$ python3 excecao.py
Começou
Traceback (most recent call last):
File "/home/ana/excecao.py", line 2, in <module>
print(10 / 0)
~~~^~~
ZeroDivisionError: division by zero
$ echo $?
1
- Começou
- A linha 1 rodou normalmente. O Python executa o programa de cima para baixo, e até a linha 1 estava tudo bem.
- Traceback (most recent call last):
- "Rastro (a chamada mais recente por último)". É o cabeçalho de todo traceback: daqui para baixo vem o caminho, e o passo mais recente fica embaixo.
- File "/home/ana/excecao.py", line 2, in <module>
- Onde aconteceu: no arquivo
/home/ana/excecao.py, na linha 2, no programa principal.<module>("módulo") é o nome que o Python dá ao código que não está dentro de nenhuma função. - print(10 / 0)
- A própria linha 2, copiada do seu arquivo para você não precisar abri-lo.
- ~~~^~~
- As marcas embaixo da linha apontam o pedaço exato que falhou. O
^fica embaixo da operação que deu errado (a divisão/) e os~embaixo das partes que ela usou (10e0). - ZeroDivisionError: division by zero
- A linha mais importante. Antes dos dois-pontos, o tipo do erro (
ZeroDivisionError, "erro de divisão por zero"); depois, a mensagem ("divisão por zero"). - echo $? → 1
- O código de saída do programa. 0 quer dizer "terminou bem"; um programa que para por causa de um erro termina com 1.
E o print("Fim")? Não aparece. Quando um erro acontece e ninguém cuida dele, o Python para o programa ali mesmo: as linhas de baixo nunca rodam. (Cuidar do erro para o programa continuar é o assunto da próxima aula, try e except.)
No Python, um erro que acontece com o programa rodando se chama exceção (em inglês, exception): algo fora do normal que interrompeu o caminho. Quando você ler "o programa lançou uma exceção" ou "deu uma exceção", é isso: deu erro.
2. Um traceback com várias chamadas
No primeiro exemplo o caminho tinha um passo só. Em programas de verdade, o código fica dividido em funções que chamam outras funções, e o traceback mostra todas. A professora da Ana tem um programa que mostra a média de cada aluno:
def media(notas):
return sum(notas) / len(notas)
def relatorio(turma):
for nome, notas in turma.items():
print(f"{nome}: {media(notas):.1f}")
turma = {"Ana": [8, 9, 10], "Bruno": [7, 6], "Carla": []}
relatorio(turma)
print("Fim do relatório")
A função media soma as notas (sum) e divide pela quantidade (len). A função relatorio passa pelos alunos do dicionário turma e mostra a média de cada um. A Carla entrou na turma ontem e ainda não tem nenhuma nota: a lista dela está vazia, [].
$ python3 notas.py
Ana: 9.0
Bruno: 6.5
Traceback (most recent call last):
File "/home/ana/notas.py", line 11, in <module>
relatorio(turma)
~~~~~~~~~^^^^^^^
File "/home/ana/notas.py", line 7, in relatorio
print(f"{nome}: {media(notas):.1f}")
~~~~~^^^^^^^
File "/home/ana/notas.py", line 2, in media
return sum(notas) / len(notas)
~~~~~~~~~~~^~~~~~~~~~~~
ZeroDivisionError: division by zero
A Ana e o Bruno saíram certinhos. Na Carla, o programa parou. Agora o traceback tem três linhas File, uma para cada passo do caminho. Leia de baixo para cima:
- A última linha:
ZeroDivisionError: division by zero. O problema foi uma divisão por zero. - A linha
Filemais de baixo:line 2, in media. A divisão aconteceu na linha 2, dentro da funçãomedia:sum(notas) / len(notas). O^está embaixo da barra da divisão. Se a divisão foi por zero, entãolen(notas)deu 0: a lista estava vazia. - Subindo um passo:
line 7, in relatorio. Quem chamou amediafoi a linha 7, dentro da funçãorelatorio. As marcas apontammedia(notas): foi essa chamada que deu errado. - Subindo mais um:
line 11, in <module>. E quem chamou arelatoriofoi a linha 11 do programa principal.
Lido de cima para baixo, o rastro conta a história na ordem em que ela aconteceu: o programa principal (linha 11) chamou relatorio, que (na linha 7) chamou media, que (na linha 2) dividiu por zero. Por isso o cabeçalho diz "a chamada mais recente por último".
| Linha do traceback | Pergunta que responde | Aqui |
|---|---|---|
A última (Tipo: mensagem) | O que deu errado? | Divisão por zero |
O File mais de baixo | Onde exatamente? | Linha 2, na função media |
Os File de cima | Como o programa chegou lá? | Linha 11 → relatorio (linha 7) → media |
O erro estourou dentro da media, mas a função não tem nada de errado: para uma lista com notas, ela funciona. O "defeito" é a turma ter uma aluna sem nota, e o programa não prever isso. O traceback mostra onde o Python tropeçou; descobrir por que é com você, e é para isso que serve subir o rastro. Você conserta este programa na missão do fim da aula.
As marcas embaixo da linha
Desde o Python 3.11, o traceback sublinha o pedaço exato da linha que falhou:
| Marca | O que aponta | Exemplo acima |
|---|---|---|
^^^^ | O ponto exato do problema: o nome que não existe, a operação que falhou, os parênteses da chamada que deu erro | ^ embaixo do /; ^^^^^^^ embaixo de (notas) |
~~~~ | As partes que participavam da operação | sum(notas) e len(notas), os dois lados da divisão |
| (nenhuma) | Quando o Python não tem um pedaço menor para apontar, ele mostra só a linha | Aparece em alguns erros da tabela da seção 4 |
Missão: este programa deveria cumprimentar os três convidados da festa da Ana, mas dá erro. Clique em Rodar, leia a última linha do traceback (e a dica que vem no fim dela) e conserte.
convidados = ["Ana", "Bia", "Caio"]
for convidado in convidados:
print(f"Olá, {convidad}!")
convidados = ["Ana", "Bia", "Caio"]
for convidado in convidados:
print(f"Olá, {convidado}!")
3. SyntaxError: o programa nem começa
Existem dois momentos em que o Python pode reclamar. Antes de rodar a primeira linha, ele lê o arquivo inteiro para ver se o texto está escrito como Python (a sintaxe: parênteses fechados, dois-pontos, indentação). Se não estiver, ele nem começa. Olhe este programa, com um parêntese faltando na linha 2:
print("Começou")
print("Olá, Ana!"
print("Fim")
$ python3 sintaxe.py
File "/home/ana/sintaxe.py", line 2
print("Olá, Ana!"
^
SyntaxError: '(' was never closed
- (nada de "Começou")
- A linha 1 estava certa e mesmo assim não rodou. Com um erro de sintaxe, nenhuma linha roda: o Python recusa o arquivo inteiro.
- (sem "Traceback")
- Não há o cabeçalho
Traceback (most recent call last):, porque não há caminho nenhum para contar: nenhuma função chegou a ser chamada. - File "/home/ana/sintaxe.py", line 2
- O arquivo e a linha. Repare que não tem
in <module>: o programa não estava rodando "dentro" de lugar nenhum. - ^
- Aponta o parêntese que foi aberto e nunca fechado.
- SyntaxError: '(' was never closed
- "Erro de sintaxe: o
(nunca foi fechado."
Compare com o excecao.py da seção 1: lá, o Começou apareceu, porque o texto do programa estava correto e o problema só surgiu no meio da execução, na hora de dividir.
Erro de sintaxe (SyntaxError) | Exceção (os outros erros) | |
|---|---|---|
| Quando acontece | Antes de rodar, quando o Python lê o arquivo | Durante a execução, na linha que falhou |
| As linhas de antes rodam? | Não, nenhuma | Sim, todas |
Tem Traceback (most recent call last):? | Não | Sim |
| Causa típica | Texto mal escrito: parêntese, aspas, dois-pontos, indentação | Texto certo, mas uma situação impossível: dividir por zero, nome que não existe, arquivo que não existe |
| Exemplos | SyntaxError, IndentationError | NameError, TypeError, ValueError, … |
O IndentationError (erro de indentação) é um tipo especial de SyntaxError: o texto está mal escrito porque os espaços do começo da linha estão errados. Ele também impede o programa de começar.
4. Os erros mais comuns, com a mensagem real
Você não precisa decorar nada desta tabela: a ideia é reconhecer o tipo do erro quando ele aparecer e saber por onde começar a procurar. Cada linha foi rodada no lab; o programa completo e o traceback inteiro vêm logo abaixo da tabela.
| Tipo | Em português | Mensagem real (última linha) | Causa típica |
|---|---|---|---|
NameError | Erro de nome | name 'nome' is not defined. Did you mean: 'nomes'? | Usou uma variável que não existe: nome digitado errado ou variável criada mais para baixo |
TypeError | Erro de tipo | can only concatenate str (not "int") to str | Misturou tipos que não combinam: texto + número |
ValueError | Erro de valor | invalid literal for int() with base 10: 'dez' | O tipo está certo (é texto), mas o valor não serve: int("dez") |
IndexError | Erro de índice | list index out of range | Pediu uma posição que a lista não tem |
KeyError | Erro de chave | 'café' | Pediu uma chave que o dicionário não tem |
ZeroDivisionError | Divisão por zero | division by zero | Dividiu por uma variável que valia 0 |
AttributeError | Erro de atributo | 'str' object has no attribute 'uper'. Did you mean: 'upper'? | Método digitado errado, ou usado no tipo errado |
FileNotFoundError | Arquivo não encontrado | [Errno 2] No such file or directory: 'notas.txt' | O arquivo não existe, ou não está na pasta onde o programa procura |
IndentationError | Erro de indentação | expected an indented block after 'if' statement on line 2 | Faltaram (ou sobraram) os espaços do começo da linha |
NameError: esse nome não existe
nomes = ["Ana", "Bia"] print(nome)
$ python3 e_name.py
Traceback (most recent call last):
File "/home/ana/e_name.py", line 2, in <module>
print(nome)
^^^^
NameError: name 'nome' is not defined. Did you mean: 'nomes'?
"O nome nome não está definido. Você quis dizer nomes?" A variável criada foi nomes, com s. Para o Python, nome e nomes são nomes tão diferentes quanto nome e batata. As marcas ^^^^ apontam exatamente a palavra que ele não conhece.
TypeError: tipos que não combinam
idade = 30
print("Idade: " + idade)
$ python3 e_type.py
Traceback (most recent call last):
File "/home/ana/e_type.py", line 2, in <module>
print("Idade: " + idade)
~~~~~~~~~~^~~~~~~
TypeError: can only concatenate str (not "int") to str
"Só dá para concatenar (juntar) str (não int) a um str." O + entre dois textos junta os textos; entre dois números, soma. Entre um texto e um número, o Python não sabe o que você quer e se recusa. Com a ordem invertida, a mensagem muda:
idade = 30 print(idade + " anos")
$ python3 e_type2.py
Traceback (most recent call last):
File "/home/ana/e_type2.py", line 2, in <module>
print(idade + " anos")
~~~~~~^~~~~~~~~
TypeError: unsupported operand type(s) for +: 'int' and 'str'
"Tipos de operando não suportados para +: int e str." É o mesmo problema dito de outro jeito: as duas mensagens dizem os dois tipos envolvidos. O conserto, nos dois casos, é uma f-string (f"Idade: {idade}") ou converter o número com str(idade) (veja Conversão de Tipos).
ValueError: o tipo é certo, o valor não
quantidade = int("dez")
$ python3 e_value.py
Traceback (most recent call last):
File "/home/ana/e_value.py", line 1, in <module>
quantidade = int("dez")
ValueError: invalid literal for int() with base 10: 'dez'
"Literal inválido para int() na base 10: 'dez'." O int() aceita texto, então o tipo está certo; mas o texto 'dez' não é feito de algarismos, então o valor não serve. É o erro clássico de quando a pessoa digita uma palavra num input() que esperava um número. (Aqui não há marcas: a linha é mostrada sem sublinhado.)
IndexError: essa posição não existe
compras = ["arroz", "feijão", "café"] print(compras[3])
$ python3 e_index.py
Traceback (most recent call last):
File "/home/ana/e_index.py", line 2, in <module>
print(compras[3])
~~~~~~~^^^
IndexError: list index out of range
"Índice da lista fora do intervalo." A lista tem 3 itens, nas posições 0, 1 e 2 (a contagem começa do zero; veja Acessando Itens). A posição 3 seria o quarto item, que não existe. O ^^^ marca o [3].
KeyError: essa chave não existe
precos = {"pão": 0.75, "leite": 5.49}
print(precos["café"])
$ python3 e_key.py
Traceback (most recent call last):
File "/home/ana/e_key.py", line 2, in <module>
print(precos["café"])
~~~~~~^^^^^^^^
KeyError: 'café'
A mensagem do KeyError é só a chave que faltou, entre aspas: 'café'. O dicionário de preços tem pão e leite, mas ninguém cadastrou o café. Repare nas aspas: elas ajudam a ver espaços e maiúsculas. No modo interativo, a Ana procurou "Leite" com L maiúsculo:
$ python3 -q
>>> precos = {"pão": 0.75, "leite": 5.49}
>>> precos["leite"]
5.49
>>> precos["Leite"]
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
precos["Leite"]
~~~~~~^^^^^^^^^
KeyError: 'Leite'
>>> exit()
No >>> (veja O Modo Interativo), o lugar do arquivo vira "<python-input-2>": o terceiro comando digitado na sessão (a contagem começa em 0). E o Python continua aberto depois do erro, esperando o próximo comando.
ZeroDivisionError: divisão por zero
total = 120 pessoas = 0 print(total / pessoas)
$ python3 e_zero.py
Traceback (most recent call last):
File "/home/ana/e_zero.py", line 3, in <module>
print(total / pessoas)
~~~~~~^~~~~~~~~
ZeroDivisionError: division by zero
Ninguém escreve / 0 de propósito. O que acontece é dividir por uma variável que, naquela vez, valia zero: a conta da pizza quando ninguém apareceu, a média de uma lista vazia.
AttributeError: esse método não existe
nome = "ana" print(nome.uper())
$ python3 e_attr.py
Traceback (most recent call last):
File "/home/ana/e_attr.py", line 2, in <module>
print(nome.uper())
^^^^^^^^^
AttributeError: 'str' object has no attribute 'uper'. Did you mean: 'upper'?
"O objeto str não tem o atributo uper. Você quis dizer upper?" Um atributo é qualquer coisa que vem depois do ponto: aqui, o método upper (deixar em maiúsculas; veja Métodos de Texto), escrito com um p só. A mensagem diz também o tipo do objeto ('str'), o que ajuda quando a variável não é do tipo que você pensava.
FileNotFoundError: esse arquivo não está aqui
arquivo = open("notas.txt")
$ python3 e_file.py
Traceback (most recent call last):
File "/home/ana/e_file.py", line 1, in <module>
arquivo = open("notas.txt")
FileNotFoundError: [Errno 2] No such file or directory: 'notas.txt'
"Arquivo ou diretório inexistente: 'notas.txt'." O [Errno 2] é o número que o sistema operacional usa para esse problema (todo programa do Linux recebe o mesmo número quando um arquivo não existe; no editor do guia, que roda dentro do navegador, sai [Errno 44]). Ou o arquivo não existe, ou ele está numa pasta diferente da que o programa está olhando. Abrir arquivos tem aula própria: Abrindo Arquivos.
IndentationError: os espaços do começo da linha
idade = 20
if idade >= 18:
print("Pode votar")
$ python3 e_indent.py
File "/home/ana/e_indent.py", line 3
print("Pode votar")
^^^^^
IndentationError: expected an indented block after 'if' statement on line 2
"Esperava um bloco indentado depois do comando if da linha 2." Depois dos dois-pontos do if, a linha de baixo precisa estar 4 espaços para dentro (veja Sintaxe e Indentação). Como é um erro de sintaxe, não há Traceback e nada roda. O erro contrário, espaços sobrando, tem outra mensagem:
preco = 10
total = preco * 2
$ python3 e_indent2.py
File "/home/ana/e_indent2.py", line 2
total = preco * 2
IndentationError: unexpected indent
"Indentação inesperada": a linha 2 começa com espaços, mas não há nenhum if, for ou def em cima pedindo um bloco.
Missão: o programa deveria mostrar Idade: 30. Rode, veja qual é o tipo do erro e conserte (dica: uma f-string resolve).
idade = 30
print("Idade: " + idade)
idade = 30
print(f"Idade: {idade}")
5. "Did you mean…?": as dicas do Python
Em vários erros, o Python termina a mensagem com uma sugestão: Did you mean: '…'?, "Você quis dizer…?". Ele procura, entre os nomes que existem, um parecido com o que você escreveu. Você já viu duas (nomes e upper). Mais algumas, todas reais:
Uma função embutida digitada errado
prin("Olá, Ana!")
$ python3 e_prin.py
Traceback (most recent call last):
File "/home/ana/e_prin.py", line 1, in <module>
prin("Olá, Ana!")
^^^^
NameError: name 'prin' is not defined. Did you mean: 'print'?
Uma variável dentro de uma função
def saudar():
nome_completo = "Ana Souza"
print(nome_complet)
saudar()
$ python3 e_local.py
Traceback (most recent call last):
File "/home/ana/e_local.py", line 6, in <module>
saudar()
~~~~~~^^
File "/home/ana/e_local.py", line 3, in saudar
print(nome_complet)
^^^^^^^^^^^^
NameError: name 'nome_complet' is not defined. Did you mean: 'nome_completo'?
De novo um rastro de dois passos: a linha 6 chamou saudar, e a linha 3, dentro dela, usou o nome errado.
Um nome importado de um módulo
from math import sqr print(sqr(16))
$ python3 e_import.py
Traceback (most recent call last):
File "/home/ana/e_import.py", line 1, in <module>
from math import sqr
ImportError: cannot import name 'sqr' from 'math' (unknown location). Did you mean: 'sqrt'?
"Não dá para importar o nome sqr do módulo math. Você quis dizer sqrt?" (A raiz quadrada; veja O Módulo math. O (unknown location), "local desconhecido", aparece porque o math vem embutido no próprio Python, sem um arquivo .py para mostrar.)
Uma palavra-chave digitada errado 3.14
contador = 0
whille contador < 3:
print(contador)
contador += 1
$ python3 e_while.py
File "/home/ana/e_while.py", line 2
whille contador < 3:
^^^^^^
SyntaxError: invalid syntax. Did you mean 'while'?
"Sintaxe inválida. Você quis dizer while?" Esta dica é novidade do Python 3.14: ele reconhece palavras-chave (while, for, if, def…) escritas com um errinho. Como é um SyntaxError, nada rodou.
As dicas Did you mean para nomes e atributos existem desde o Python 3.10, e a do import desde o 3.12. A dica de palavra-chave é do 3.14: num Python 3.13 (o do Debian 13, por exemplo), o mesmo whille dá só SyntaxError: invalid syntax, sem sugestão. As marcas ^^^/~~~ embaixo da linha existem desde o 3.11.
O Python sugere o nome mais parecido que existe, mas não sabe o que você queria. Se você escreveu totl querendo uma variável que ainda nem criou, ele pode sugerir outra coisa que não tem nada a ver. E nem todo erro tem dica: o KeyError da seção 4 não sugeriu 'leite' para 'Leite'.
Formas de investigar um erro
Diante de um traceback, há alguns caminhos. Os bons programadores usam todos, nesta ordem:
| Passo | Como | Quando ajuda |
|---|---|---|
| 1. Ler a última linha | O tipo e a mensagem (e a dica Did you mean, se houver) | Sempre. Muitas vezes é o suficiente: nome digitado errado, parêntese aberto |
| 2. Ir à linha indicada | O File … line N mais de baixo, e as marcas ^^^ | Para ver exatamente o pedaço que falhou |
| 3. Subir o rastro | As linhas File de cima, uma a uma | Quando a linha do erro parece certa e o problema veio de quem chamou (como a turma com a Carla) |
| 4. Mostrar os valores | Um print() antes da linha do erro: print(notas) | Quando você não entende por que uma variável tem aquele valor |
| 5. Procurar a mensagem | Copiar a última linha (sem os seus nomes) num buscador | Mensagens que você nunca viu; quase sempre alguém já perguntou |
Depurar com mais ferramentas (parar o programa no meio, olhar as variáveis passo a passo) tem aula própria: Depurando com pdb e breakpoint().
Quando dá errado
A Ana escreveu um programa que pergunta a idade e mostra a idade do ano que vem. Ela digitou 30:
idade = input("Sua idade: ")
print(idade + 1)
$ python3 e_str_int.py
Sua idade: 30
Traceback (most recent call last):
File "/home/ana/e_str_int.py", line 2, in <module>
print(idade + 1)
~~~~~~^~~
TypeError: can only concatenate str (not "int") to str
O traceback acusa a linha 2. Mas a linha 2 é uma soma inocente; o defeito está na linha 1: o input() sempre devolve texto, então idade vale "30" (com aspas), e não 30. A mensagem dá a pista: str é o tipo de idade. Como consertar: converter na hora de ler, idade = int(input("Sua idade: ")) (veja input()). Moral: quando a linha indicada parece certa, pergunte "de onde veio esse valor?".
Num traceback comprido, como o do notas.py, quem lê de cima para baixo vê primeiro line 11, relatorio(turma) e vai procurar o problema na linha 11, que está perfeita. A informação útil está embaixo: o tipo do erro e o File mais de baixo. Como evitar: comece sempre pela última linha e suba.
SyntaxError
No sintaxe.py, o Python apontou a linha 2, onde o parêntese foi aberto, mesmo o "buraco" ficando no fim dela. Em erros de parênteses, colchetes e aspas, o defeito costuma estar na linha indicada ou logo antes dela: confira se cada ( tem o seu ). A maioria dos editores de código colore o par do parêntese quando você põe o cursor nele.
A dica Did you mean: 'convidado'? estava no fim da linha, e quem não lê a linha até o fim perde. Nos tracebacks desta aula, a dica sozinha já resolvia sete erros. Leia a última linha inteira, até o ponto de interrogação.
Referência rápida
| Parte do traceback | O que diz |
|---|---|
Traceback (most recent call last): | Começa o rastro; o passo mais recente vem por último. Só aparece em exceções (não em SyntaxError) |
File "…", line N, in função | Arquivo, linha e função de cada passo. <module> = programa principal; <python-input-N> = comando digitado no >>> |
| A linha de código copiada | A linha daquele passo, como está no arquivo |
^^^ e ~~~ | O pedaço exato que falhou (^) e as partes envolvidas (~) |
Tipo: mensagem | A última linha: o que deu errado |
Did you mean: '…'? | Um palpite do Python com o nome parecido mais próximo |
echo $? → 1 | O programa terminou por causa de um erro não tratado |
| Tipo | Pergunte-se |
|---|---|
SyntaxError / IndentationError | O texto está bem escrito? Parênteses, aspas, dois-pontos, espaços |
NameError | O nome está escrito igual onde a variável foi criada? Ela foi criada antes desta linha? |
TypeError | Que tipo tem cada valor? (type(x); veja Descobrindo o Tipo) |
ValueError | O valor faz sentido para essa função? (int("dez")) |
IndexError | Quantos itens a lista tem? (len(lista); a última posição é len - 1) |
KeyError | A chave existe, com essas maiúsculas e acentos? |
ZeroDivisionError | Por que o divisor valia zero? |
AttributeError | O método existe para esse tipo? Está escrito certo? |
FileNotFoundError | O arquivo existe? Está na pasta onde o programa roda? |
A lista completa dos tipos de erro do Python está em Exceções Embutidas.
Exercícios
1. Qual é o tipo?
A última linha de um traceback é KeyError: 'açúcar'. Escreva só o tipo do erro:
2. Em qual linha?
Neste traceback, em qual linha do arquivo a exceção realmente aconteceu?
$ python3 loja.py
Vendas do dia: 0
Traceback (most recent call last):
File "/home/ana/loja.py", line 9, in <module>
fechar_caixa(vendas)
~~~~~~~~~~~~^^^^^^^^
File "/home/ana/loja.py", line 5, in fechar_caixa
return total / quantidade
~~~~~~^~~~~~~~~~~~
ZeroDivisionError: division by zero
3. Por onde se começa a ler um traceback?
4. Um programa começa com print("Oi") e tem um parêntese sem fechar na linha 5. O que aparece ao rodar?
5. int("12,5") dá ValueError: invalid literal for int() with base 10: '12,5'. O que a mensagem quer dizer?
6. lista = [10, 20, 30] e depois print(lista[3]). Qual erro aparece?
Missão final: a média da Carla
Missão: este é o programa da seção 2. Rode e leia o traceback de baixo para cima. Depois, conserte a função relatorio para que, quando a lista de notas estiver vazia, ela mostre Carla: sem notas em vez de chamar a media. Dica: uma lista vazia é "falsa" num if (veja Booleanos), então if notas: quer dizer "se a lista tem alguma nota".
def media(notas):
return sum(notas) / len(notas)
def relatorio(turma):
for nome, notas in turma.items():
print(f"{nome}: {media(notas):.1f}")
turma = {"Ana": [8, 9, 10], "Bruno": [7, 6], "Carla": []}
relatorio(turma)
print("Fim do relatório")
def media(notas):
return sum(notas) / len(notas)
def relatorio(turma):
for nome, notas in turma.items():
if notas:
print(f"{nome}: {media(notas):.1f}")
else:
print(f"{nome}: sem notas")
turma = {"Ana": [8, 9, 10], "Bruno": [7, 6], "Carla": []}
relatorio(turma)
print("Fim do relatório")
Com o conserto, o programa mostra as quatro linhas e chega ao fim:
$ python3 notas.py Ana: 9.0 Bruno: 6.5 Carla: sem notas Fim do relatório
Resumo
- O traceback é o relatório do erro. Leia de baixo para cima: a última linha diz o que (tipo e mensagem); o
Filemais de baixo diz onde; os de cima contam o caminho (quem chamou quem). File "…", line N, in função:<module>é o programa principal. As marcas^^^apontam o pedaço que falhou;~~~, as partes envolvidas.- Um erro não tratado para o programa ali: as linhas de baixo não rodam, e o código de saída é 1.
SyntaxError(eIndentationError): o texto está mal escrito, e nenhuma linha roda; não háTraceback (most recent call last):. As outras são exceções: acontecem no meio, depois de as linhas anteriores rodarem.- Os mais comuns:
NameError(nome),TypeError(tipos),ValueError(valor),IndexError(posição),KeyError(chave),ZeroDivisionError,AttributeError(método),FileNotFoundError(arquivo),IndentationError(espaços). Did you mean: '…'?é um palpite do Python com o nome parecido; no 3.14 vale até para palavras-chave.- A linha do erro nem sempre é a do defeito: pergunte de onde veio o valor.