W3docs

Python Try...Except

Aprenda os blocos try, except, else e finally do Python com exemplos claros. Trate ZeroDivisionError, ValueError, FileNotFoundError e muito mais.

Quando o Python encontra um erro em tempo de execução, ele lança uma exceção — um objeto que representa o que deu errado. Sem nenhum tratamento, uma exceção encerra o programa imediatamente. A instrução try...except permite capturar essas exceções, responder a elas de forma elegante e manter o programa em execução.

Este capítulo aborda:

  • O bloco try / except — capturando uma exceção específica
  • Capturando detalhes da exceção com as
  • Múltiplas cláusulas except e capturando várias exceções ao mesmo tempo
  • O bloco else — código que só é executado quando nenhuma exceção ocorre
  • O bloco finally — código de limpeza que sempre é executado
  • Exceções integradas comuns e quando elas ocorrem
  • Relançando exceções
  • Boas práticas e erros comuns

O bloco try...except básico

Envolva o código que pode falhar em um bloco try. Se o Python lançar uma exceção, a execução salta para o bloco except correspondente em vez de encerrar o programa.

python— editable, runs on the server

Saída:

Error: division by zero

O Python tenta a divisão, lança ZeroDivisionError e o bloco except trata o erro. A cláusula as e vincula o objeto de exceção a e para que você possa inspecionar ou registrar a mensagem.

Se o bloco try for concluído com sucesso, o bloco except é completamente ignorado.

Capturando um tipo específico de exceção

Sempre nomeie o tipo de exceção que você espera. Capturar um tipo nomeado deixa sua intenção clara e evita ocultar acidentalmente bugs não relacionados.

try:
    number = int("abc")
except ValueError as e:
    print(f"Could not convert: {e}")

Saída:

Could not convert: invalid literal for int() with base 10: 'abc'

int("abc") lança ValueError porque "abc" não é um inteiro válido. Especificar ValueError na cláusula except significa que qualquer outra exceção inesperada ainda será propagada e aparecerá como erro, em vez de ser silenciosamente ignorada.

Múltiplas cláusulas except

Um único bloco try pode ter várias cláusulas except — o Python as verifica de cima para baixo e executa a primeira correspondência.

def safe_index(items, index):
    try:
        return items[index]
    except IndexError:
        print("Index out of range.")
    except TypeError:
        print("Index must be an integer.")

safe_index([1, 2, 3], 10)   # IndexError
safe_index([1, 2, 3], "a")  # TypeError

Saída:

Index out of range.
Index must be an integer.

A ordem importa: coloque tipos de exceção mais específicos antes dos mais amplos para que o tratador específico seja executado primeiro.

Capturando múltiplas exceções em uma única cláusula

Quando duas ou mais exceções merecem a mesma resposta, agrupe-as em uma tupla:

try:
    value = int("not-a-number")
except (ValueError, TypeError) as e:
    print(f"Input error: {e}")

Saída:

Input error: invalid literal for int() with base 10: 'not-a-number'

O bloco else

O bloco else é executado somente quando o bloco try é concluído sem lançar nenhuma exceção. Use-o para código que deve ser executado em caso de sucesso, mas que não precisa de proteção contra erros:

try:
    result = 10 / 2
except ZeroDivisionError:
    print("Cannot divide by zero.")
else:
    print(f"Division succeeded. Result: {result}")

Saída:

Division succeeded. Result: 5.0

Manter a lógica do caminho de sucesso no else (em vez de no final do try) evita capturar acidentalmente exceções que o próprio código do caminho de sucesso possa lançar.

O bloco finally

O bloco finally é executado independentemente do resultado — seja o bloco try bem-sucedido, uma exceção capturada ou uma exceção propagada sem ser capturada. Use-o para limpeza: fechar arquivos, liberar bloqueios ou desconectar de um banco de dados.

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Error caught.")
finally:
    print("This always runs — cleanup goes here.")

Saída:

Error caught.
This always runs — cleanup goes here.

Mesmo que você comente o bloco except, o finally ainda é executado antes do Python propagar a exceção.

Estrutura completa de relance

try:
    # code that may raise an exception
except SomeException as e:
    # handle the exception
except (AnotherError, YetAnother):
    # handle either of these
else:
    # runs only when try succeeded
finally:
    # always runs

Exceções integradas comuns

ExceçãoQuando ocorre
ZeroDivisionErrorDivisão ou módulo por zero
ValueErrorTipo correto, valor errado (ex.: int("abc"))
TypeErrorOperação aplicada ao tipo errado
IndexErrorÍndice de sequência fora do intervalo
KeyErrorChave de dicionário não encontrada
FileNotFoundErrorArquivo ou diretório não existe
AttributeErrorObjeto não possui tal atributo
ImportErrorMódulo não pode ser importado
NameErrorNome de variável não está definido

Todas essas exceções herdam da classe base Exception. Você pode capturar Exception para tratar qualquer uma delas em uma única cláusula, mas prefira tipos específicos sempre que possível.

Tratando um arquivo ausente

try:
    with open("data.txt", "r") as file:
        content = file.read()
except FileNotFoundError:
    print("Error: File not found.")

Saída (quando data.txt não existe):

Error: File not found.

Relançando uma exceção

Às vezes, você deseja registrar uma exceção ou fazer uma limpeza parcial, mas ainda permitir que ela se propague para o chamador. Use um raise simples dentro de um bloco except:

def process():
    try:
        result = 10 / 0
    except ZeroDivisionError:
        print("Logging error...")
        raise  # re-raises the original ZeroDivisionError

try:
    process()
except ZeroDivisionError as e:
    print(f"Outer handler caught: {e}")

Saída:

Logging error...
Outer handler caught: division by zero

O raise simples preserva o traceback original para que a depuração não seja mais difícil do que sem o tratador.

Capturando a classe base Exception

Você pode usar Exception como um captura-tudo para qualquer erro que não encerre o sistema:

try:
    result = 10 / 0
except Exception as e:
    print(f"An error occurred: {type(e).__name__}: {e}")

Saída:

An error occurred: ZeroDivisionError: division by zero

type(e).__name__ fornece o nome específico da classe mesmo quando você captura via a classe base. Isso é útil em tratadores de nível superior onde você deseja registrar todos os erros inesperados.

Bare except — e por que evitá-lo

Um bare except (sem nenhum tipo de exceção) captura literalmente tudo, incluindo KeyboardInterrupt (Ctrl+C) e SystemExit, tornando o programa difícil de interromper:

# Avoid this pattern
try:
    result = 10 / 0
except:
    print("Some error occurred")

Prefira except Exception se precisar de uma captura ampla, pois isso ainda permite que KeyboardInterrupt e SystemExit se propaguem normalmente.

Boas práticas

  • Seja específico. Capture o tipo de exceção mais restrito que fizer sentido.
  • Não silencie exceções. No mínimo, registre o erro; nunca deixe um bloco except vazio.
  • Use else para o código do caminho de sucesso. Isso mantém o bloco try o menor possível.
  • Use finally para limpeza. Ou, ainda melhor, use uma instrução with — veja Python with Statement.
  • Evite bare except. Use except Exception se precisar de uma rede ampla.
  • Relance quando apropriado. Se você não puder tratar completamente o erro, deixe-o se propagar com raise.

Para lançar exceções deliberadamente e criar suas próprias classes de exceção, veja Python raise and Custom Exceptions.

Prática

Prática
What is the functionality of 'Try' and 'Except' in Python?
What is the functionality of 'Try' and 'Except' in Python?
Was this page helpful?