Menu

Tipos de erros e debugging em Python: lendo tracebacks e corrigindo erros comuns

Um passeio pelos erros Python que você vai encontrar com mais frequência — KeyError, ValueError, ModuleNotFoundError, EOFError — e os hábitos de debug que os corrigem rápido.

Erros são como o Python te diz o que aconteceu

Todo erro do Python é um objeto com tipo, mensagem e um traceback — a cadeia de chamadas que levou até ele. Ler bem é a habilidade de debug mais importante que você pode adquirir. Essa página é um passeio pelos erros que você de fato vai encontrar, e os hábitos que deixam o conserto rápido.

Para uma olhada mais profunda na mecânica de try/except e lançar os seus, a página de exceções cobre a sintaxe. Esta página é sobre os erros específicos e como lê-los.

Lendo um traceback

Rode algo que quebra:

def divide(a, b):
    return a / b

def report(values):
    for v in values:
        print(divide(10, v))

report([5, 2, 0])

O Python imprime algo como:

Traceback (most recent call last):
  File "script.py", line 8, in <module>
    report([5, 2, 0])
  File "script.py", line 6, in report
    print(divide(10, v))
  File "script.py", line 2, in divide
    return a / b
ZeroDivisionError: division by zero

Leia de baixo para cima:

  1. ZeroDivisionError: division by zero — o tipo e a mensagem da exceção. É o que deu errado.
  2. return a / b em divide, linha 2 — a linha que de fato disparou.
  3. print(divide(10, v)) em report, linha 6 — a chamada que disparou.
  4. report([5, 2, 0]) no nível de módulo, linha 8 — onde começou.

O frame do fundo é quase sempre onde vai a correção. Quando uma biblioteca lança um erro lá no fundo dela, suba o traceback até o primeiro frame do seu código — essa é a chamada para a qual você passou uma entrada ruim.

Os erros que você mais vai encontrar

NameError

main.py
Output
Click Run to see the output here.

"Name 'mesage' is not defined." Causado por typos ou uso de variável antes de ser atribuída. A mensagem de erro do Python geralmente sugere um substituto provável em versões recentes ("Did you mean 'message'?").

Correção: confira ortografia e escopo. Se o nome só existe dentro de uma função, você não pode ler de fora.

TypeError

main.py
Output
Click Run to see the output here.

"Can only concatenate str (not 'int') to str." Tipo errado para a operação. Clássicos: somar string com número, chamar algo que não é callable, passar o número errado de argumentos para uma função.

Correção: converta tipos explicitamente (str(30), int("30")) ou inspecione o que está passando. Uma f-string geralmente lê melhor do que concatenação com + entre tipos: f"age: {30}".

ValueError

main.py
Output
Click Run to see the output here.

"Invalid literal for int() with base 10: 'hello'." O tipo está certo — int() aceita string — mas o valor não encaixa. Comum com int(), float(), parsing de datas e funções que recebem argumentos com limite.

Correção: valide antes de converter, ou capture o erro e trate:

main.py
Output
Click Run to see the output here.

KeyError

main.py
Output
Click Run to see the output here.

"KeyError: 'charlie'." A chave não está no dict. Três correções idiomáticas, escolhidas pela intenção:

main.py
Output
Click Run to see the output here.

Para um dict em que chaves faltando devem se autoinicializar, collections.defaultdict vale uma olhada.

IndexError

main.py
Output
Click Run to see the output here.

"List index out of range." Você pediu uma posição que a sequência não tem.

Correção: proteja com checagem de tamanho, use -1 para referenciar o último elemento ou use fatiamento (numbers[5:6] retorna [] em vez de lançar).

AttributeError

main.py
Output
Click Run to see the output here.

"'NoneType' object has no attribute 'upper'." Você chamou um método em algo que não tem. Quase sempre significa que uma variável é de um tipo inesperado — muitas vezes None quando você esperava um valor de verdade.

Correção: descubra de onde o None veio. print(type(var)) ou um breakpoint antes do erro é o jeito mais rápido. Funções que "às vezes falham" geralmente retornam None; confira o retorno delas antes de chamar métodos.

ModuleNotFoundError (e ImportError)

import fastapi

"No module named 'fastapi'." O pacote não está instalado no interpretador Python que seu script usa. Duas causas comuns:

  1. Você realmente não instalou. Rode python -m pip install fastapi no ambiente certo.
  2. Você instalou, mas num Python diferente. Acontece o tempo todo no macOS quando pip e python apontam para instalações diferentes.

A correção confiável é instalar com o mesmo interpretador que você roda:

python -m pip install fastapi

Se você usa um ambiente virtual (e deveria), garanta que está ativado antes do pip install e do python script.py.

FileNotFoundError

with open("settings.yaml") as f:
    config = f.read()

"[Errno 2] No such file or directory: 'settings.yaml'." O caminho não existe relativo a onde o script está rodando.

Correção: imprima os.getcwd() no topo do script para confirmar onde o Python está olhando. Use caminhos absolutos ou pathlib.Path(__file__).parent / "settings.yaml" para ancorar caminhos no local do próprio script.

EOFError

name = input("Name: ")

"EOF when reading a line." input() tentou ler do stdin e não recebeu nada — ou a entrada foi piped de uma fonte vazia, ou você apertou Ctrl-D no prompt.

Correção: se o pipe é legítimo, envolva a chamada:

try:
    name = input("Name: ")
except EOFError:
    name = "anonymous"

No editor do navegador destes docs, o runtime simula entrada; você não vai cair nisso aqui.

IndentationError e SyntaxError

IndentationError: expected an indented block after function definition on line 2

Esses são especiais — disparam antes do seu programa rodar. O Python recusou parsear o arquivo.

  • IndentationError — o corpo de um def, if, for, etc. está faltando ou desalinhado. A maioria dos editores visualiza indentação; ligue "show whitespace" para pegar tabs e espaços misturados.
  • SyntaxError — você esqueceu dois pontos, parentetizou mal ou escreveu errado uma palavra-chave. Versões recentes do Python apontam uma seta (^) para o caractere ofensor.

Correção: a mensagem nomeia a linha. Vá ver. Se nada parece obviamente errado naquela linha, confira a linha acima — um parêntese não fechado algumas linhas antes muitas vezes aparece como erro de sintaxe bem depois.

RuntimeError

Um pega-tudo para "algo deu errado em tempo de execução que não é um dos erros mais específicos". RecursionError (passou da profundidade de recursão) é uma especialização comum. Código de biblioteca muitas vezes lança RuntimeError quando está num estado ruim.

Correção: leia a mensagem; geralmente é descritiva. Se a recursão é a causa, ou converta para laço iterativo ou aumente sys.setrecursionlimit em casos raros.

Debug com print

Antes de recorrer a um debugger de verdade, print() — ou melhor, a forma f"{var=}" — pega a maioria dos bugs:

main.py
Output
Click Run to see the output here.

f"{var=}" imprime a expressão como fonte e o valor, então você não precisa redigitar o nome na string de formato. Rode o script, varra a saída, ache a linha onde um valor virou errado. A maioria dos bugs "misteriosos" fica óbvia em três ou quatro prints bem colocados.

Limpe os prints antes de commitar. logging.debug(...) é mais gentil do que print para código que você vai lançar — dá para ligar e desligar o debug logging sem editar linhas.

breakpoint() e pdb

Quando print não basta, breakpoint() te joga no debugger interativo do Python naquele ponto:

def discount(price, percent):
    breakpoint()
    return price * (1 - percent / 100)

discount(100, 20)

Rode o script num terminal de verdade. Você vai aterrissar num prompt (Pdb). Alguns comandos para saber:

  • p variavel — imprime uma variável.
  • n — passa para a próxima linha.
  • s — entra numa chamada de função.
  • c — continua rodando até o próximo breakpoint ou o fim.
  • q — sai.
  • l — lista o código em volta da linha atual.

Debuggers de IDE (VS Code, PyCharm) envolvem o mesmo protocolo numa GUI — breakpoints setados na margem, um painel mostrando variáveis. Escolha o que parecer de menor atrito.

Hábitos que reduzem os erros que você pega

  • Use nomes de variáveis descritivos. Metade do ruído de TypeError e AttributeError some quando você não esquece o que está numa variável.
  • Valide entradas na fronteira. Parseie e cheque entrada de usuário / conteúdo de arquivo uma vez, no topo da função. O resto do código pode confiar nos valores.
  • Falhe barulhento, não silencioso. Um except Exception: pass vazio esconde os erros que você de fato precisa ver. Capture exceções específicas, trate com deliberação e deixe o resto propagar.
  • Leia o fundo do traceback primeiro. Cada minuto gasto aprendendo a ler tracebacks se paga cem vezes.

A maioria dos erros não é mistério — são typos de uma linha ou erros de tipo errado com uma mensagem clara. Confie na mensagem de erro; geralmente está certa.

Você chegou

É o fim da seção de referência. Você foi de "o que é Python?" por variáveis, controle de fluxo, coleções, funções, classes, iteração, dados do mundo real e erros. Daqui, os próximos passos têm formato de projeto: escolha algo que queira construir e trabalhe de trás para a frente até as peças que precisa aprender mais a fundo. Essas páginas continuarão aqui quando você voltar com uma pergunta específica.

Perguntas frequentes

O que é um KeyError em Python?

KeyError é lançado quando você busca uma chave de dict que não existe. users["missing"] lança KeyError: 'missing'. As alternativas seguras são users.get("missing", default), users.get("missing") (retorna None), ou uma checagem explícita if key in users:.

O que é um EOFError em Python?

EOFError (fim de arquivo) é lançado quando input() não consegue ler nada porque o stream de entrada fechou. Você vai ver com mais frequência quando um script que usa input() é piped sem dados, ou quando você aperta Ctrl-D no prompt interativo. Proteja com try/except EOFError se seu script precisa lidar com entrada via pipe.

O que é um ModuleNotFoundError?

ModuleNotFoundError significa que import X não achou um módulo chamado X. Ou o pacote não está instalado (pip install X), ou está instalado num Python diferente do que está rodando seu código (muito comum quando você tem vários Pythons). python -m pip install X resolve o segundo caso usando o mesmo interpretador.

Como leio um traceback em Python?

Leia de baixo para cima. A última linha é o tipo e a mensagem da exceção — a coisa específica que deu errado. As linhas acima mostram a pilha de chamadas que levou até lá, com seu próprio código geralmente perto do fundo. Vá para o arquivo + linha do frame mais ao fundo que é seu; é ali que vai a correção.

Aprenda a programar com o Coddy

COMEÇAR