Tratando erros em Python com try, except, finally
Ao programar em Python, podemos encontrar dois tipos principais de erros. O primeiro tipo é composto pelos erros de sintaxe (syntax errors), que surgem quando há alguma violação das regras de sintaxe da linguagem ao escrever o código. Quando trabalhamos em um ambiente de desenvolvimento integrado (IDE), como o PyCharm, a própria IDE pode detectar esses erros de sintaxe e destacá-los de alguma forma.
O segundo tipo de erro é o erro de execução (runtime error), que ocorre durante a execução do programa. Esses erros também são chamados de exceções. Vejamos um exemplo com a conversão de uma string para um número:
string = "5"
number = int(string)
print(number)Esse código será executado sem problemas, pois a string "5" pode ser convertida em um número. No entanto, observe o próximo exemplo:
string = "hello"
number = int(string)
print(number)Ao executar esse código, será lançada uma exceção ValueError, pois a string "hello" não pode ser convertida em um número:
ValueError: invalid literal for int() with base 10: 'hello'
Aqui, é evidente que "hello" não é um número, mas podemos lidar com entradas de usuário, que podem não ser exatamente o que esperamos:
string = input("Digite um número: ")
number = int(string)
print(number)Caso ocorra uma exceção, a execução do programa é interrompida. Para evitar esse comportamento e tratar exceções em Python, utilizamos a estrutura try...except.
try...except
A estrutura try...except é definida da seguinte forma:
try:
# instruções
except [Tipo_de_Exceção]:
# instruçõesTodo o código principal, onde pode ocorrer uma exceção, é colocado após a palavra-chave try. Se uma exceção é gerada nesse bloco, a execução é interrompida e o fluxo passa para o bloco except.
Após except, podemos opcionalmente especificar o tipo de exceção que será tratada (por exemplo, ValueError ou KeyError). Abaixo do except, são colocadas as instruções que serão executadas em caso de exceção.
Vamos ver um exemplo com o tratamento de exceção ao converter uma string em um número:
try:
number = int(input("Digite um número: "))
print("Número digitado:", number)
except:
print("Falha na conversão")
print("Programa finalizado")Ao inserir uma string:
Digite um número: hello Falha na conversão Programa finalizado
Como se vê na saída do console, ao inserir uma string, a conversão falha e o fluxo é transferido para o bloco except.
Ao inserir um número válido:
Digite um número: 22 Número digitado: 22 Programa finalizado
Agora, tudo funciona normalmente, sem exceções, então o bloco except não é executado.
Bloco finally
Ao tratar exceções, também é possível utilizar o bloco opcional finally. A principal característica desse bloco é que ele é executado independentemente de a exceção ter ocorrido ou não:
try:
number = int(input("Digite um número: "))
print("Número digitado:", number)
except:
print("Falha na conversão")
finally:
print("Programa finalizado")Normalmente, o bloco finally é utilizado para liberar recursos utilizados, como o fechamento de arquivos.
Vale destacar que o bloco finally não trata exceções. Se usarmos apenas o finally sem o bloco except, uma exceção que ocorra fará o programa ser encerrado de forma abrupta, como no exemplo a seguir com uma divisão por zero:
try:
number = 3/0 # lança a exceção ZeroDivisionError
print(number)
finally:
print("Programa finalizado")Ao executar esse código, a exceção ZeroDivisionError será gerada e o programa será encerrado abruptamente, sem executar o bloco finally.