Advertisement
  1. Code
  2. Python

Como tratar exceções em Python

Scroll to top
Read Time: 8 min

Portuguese (Português) translation by Jonathan Ramos (you can also view the original English article)

É muito comum encontrar erros durante a execução de um programa. Dois tipos comuns de erros que você pode ter que lidar são exceções e erros de sintaxe. Erros de sintaxe ocorrem quando você digita o código incorretamente. Em tais casos, a linha errônea é lida pelo analisador com uma seta apontando para a linha onde o erro foi detectado.

Exceções são diferentes de erros de sintaxe. Elas ocorrem durante a execução de um programa, quando algo inesperado acontece. Por exemplo, digamos que você está pedindo ao usuário um número para realizar uma divisão. Agora, se o usuário insere uma sequência de caracteres em vez de um número e você tenta dividir essa entrada por algum número, o programa terá como saída um TypeError.

Quando você não manipula corretamente as exceções, o programa vai fechar abruptamente, pois ele não sabe o que fazer nesses casos. O código a seguir é um exemplo:

1
keep_asking = True
2
3
while keep_asking:
4
    x = int(input("Enter a number: "))
5
    print("Dividing 50 by", x,"will give you :", 50/x)

Desde que seja inserido um número inteiro na entrada, o programa irá funcionar corretamente. No entanto, assim que você inserir uma sequência de caracteres ou até mesmo um número decimal como entrada, você receberá uma exceção do tipo ValueError.

Neste tutorial, você aprenderá como criar exceções em Python e como manipulá-las corretamente.

Algumas exceções comuns

Aqui estão algumas exceções básicas que você pode encontrar ao programar. Você pode ler sobre muitas exceções internas no site oficial.

  • NameError: exceção gerada quando o programa não consegue encontrar um nome local ou global. O nome que não pôde ser encontrado é incluído na mensagem de erro.
  • TypeError: exceção gerada quando é passado um objeto de um tipo diferente do tipo que a função espera como argumento. Mais detalhes sobre o tipo errado são fornecidos na mensagem de erro.
  • ValueError: essa exceção ocorre quando um argumento de uma função tem o tipo certo, mas um valor inadequado.
  • NotImplementedError: essa exceção é gerada quando um objeto deveria dar suporte a uma operação, mas não foi implementado ainda. Você não deve usar este erro quando determinada função não dá suporte ao tipo de argumento de entrada. Nessas situações, disparar uma exceção TypeError é mais apropriado.
  • ZeroDivisionError: exceção gerada quando você fornece um zero como segundo argumento para uma divisão ou módulo.
  • FileNotFoundError: essa exceção é gerada quando o arquivo ou diretório que o programa solicitou não existe.

Assim como os nomes acima, a maioria das exceções têm nomes auto-explicativos.

Manipulando exceções

O código no início do artigo pediu que os usuários inserissem um inteiro como entrada. Se o usuário não fornecer um número inteiro, o programa parava a execução e gerava uma exceção de valor inválido. Nesta seção, vamos escrever algum código para informar ao usuário que sua entrada não é um valor inteiro válido.

A primeira etapa do processo é incluir o código que você acha que pode elevar a uma exceção dentro da cláusula try. O próximo passo é usar a palavra-chave except para lidar com a exceção que ocorreu no código acima. O código modificado para entrada do usuário ficará assim:

1
keep_asking = True
2
3
while keep_asking:
4
    try:
5
        x = int(input("Please enter a number: "))
6
        print("Dividing 50 by", x,"will give you :", 50/x)
7
    except ValueError:
8
        print("The input was not an integer. Please try again...")

O que acontece aqui é que o programa tenta executar o código dentro a cláusula try. Se nenhuma exceção foi disparada, o programa ignora a cláusula except e o resto do código é executado normalmente. Se uma exceção é gerada, o programa ignora o restante do código dentro da cláusula try e o tipo de exceção gerada é combinada com o nome da exceção após a palavra-chave except. Caso combinem, o código dentro a cláusula except é executado primeiro, e depois o resto do código após a cláusula try é executado normalmente.

Quando você insere um inteiro como entrada, o programa dá-lhe o resultado final da divisão. Quando um valor não-inteiro é fornecido, o programa imprime uma mensagem pedindo para tentar e inserir um número inteiro novamente. Observe que, neste momento, o programa não fecha abruptamente quando você fornece uma entrada inválida.

Você pode ter múltiplas cláusulas except para manipular exceções diferentes. Por favor, tenha em mente que esses manipuladores só vão lidar com exceções ocorridas na cláusula try correspondente. Exceções geradas dentro de outras cláusulas não serão tratadas.

Você pode também manipular várias exceções usando uma única cláusula except, passando essas exceções à cláusula como um tuple.

1
except (ZeroDivisionError, ValueError, TypeError):
2
    print("Something has gone wrong..")
3
    # code to deal with the exception

Finalmente, você também pode deixar o nome da exceção após a palavra-chave except. Isso geralmente não é recomendado, pois o código não captura todas as exceções e as trata da mesma forma. Isto não é o ideal quando você está lidando com um exceção TypeError da mesma forma que você lida com uma exceção ZeroDivisionError. Quanto ao tratamento de exceções, é melhor ser o mais específico possível e só capturar o que você pode manipular.

Uma forma possível de capturar todas as exceções é imprimir corretamente o erro da exceção na tela como no código a seguir:

1
import math
2
import sys
3
4
try:
5
    result = math.factorial(2.4)
6
except:
7
    print("Something Unexpected has happened.",sys.exc_info()[0])
8
else:
9
    print("The factorial is", result)

Usando a cláusula else

Você também pode usar uma cláusula else em uma declaração try ... except. A cláusula else serve para conter o código que precisa ser executado se a cláusula try não lançou nenhuma exceção. Isso pode ser útil para certificar-se de que você não adicione código ao bloco try cujo as exceções não pretende tratar. Uma coisa que vale mencionar é que se você decidir usar uma cláusula else, você deverá incluí-la após todas as cláusulas except, mas antes o bloco finally.

No nosso caso, nós poderíamos mover a linha que imprime o resultado da nossa divisão para o bloco else.

1
keep_asking = True
2
3
while keep_asking:
4
    try:
5
        x = int(input("Please enter a number: "))
6
    except ValueError:
7
        print("The input was not a valid integer. Please try again...")
8
    else:
9
        print("Dividing 50 by", x,"will give you :", 50/x)

Limpando o código utilizando a cláusula finally

Digamos que você tenha escrito algum código dentro do bloco try que deve executar uma tarefa utilizando uma grande quantidade de recursos. É importante liberar esses recursos após usá-los. Isto pode ser facilmente conseguido usando a cláusula finally.

O código dentro da cláusula finally sempre é executado independentemente se o bloco try gerou uma exceção. Você pode verificar isto executando o seguinte código:

1
keep_asking = True
2
3
while keep_asking:
4
    try:
5
        x = int(input("Please enter a number: "))
6
    except ValueError:
7
        print("The input was not a valid integer. Please try again...")
8
    else:
9
        print("Dividing 50 by", x,"will give you :", 50/x)
10
    finally:
11
        print("Already did everything necessary.")

Se qualquer uma das cláusulas except que você especificou não tratar a exceção levantada, a mesma exceção é gerada novamente após a execução do código dentro do bloco finally.

Um exemplo mais complexo

Nesta seção, vamos escrever um programa para lidar com várias exceções. Como nos exemplos anteriores, nós estaremos realizando algumas operações matemáticas. No entanto, desta vez vamos ter uma lista como entrada.

O código a seguir verifica se há duas exceções, TypeError e ValueError. O bloco else é usado para imprimir o fatorial. Você pode ver na saída que esse código é executado somente quando nenhuma exceção é gerada.

1
import math
2
3
number_list = [10,-5,1.2,'apple']
4
5
for number in number_list:
6
    try:
7
        number_factorial = math.factorial(number)
8
    except TypeError:
9
        print("Factorial is not supported for given input type.")
10
    except ValueError:
11
        print("Factorial only accepts positive integer values.", number," is not a positive integer.")
12
    else:
13
        print("The factorial of",number,"is", number_factorial)
14
    finally:
15
        print("Release any resources in use.")

O código acima produz a seguinte saída:

1
The factorial of 10 is 3628800
2
Releasing any resources in use.
3
4
Factorial only accepts positive integer values. -5  is not a positive integer.
5
Releasing any resources in use.
6
7
Factorial only accepts positive integer values. 1.2  is not a positive integer.
8
Releasing any resources in use.
9
10
Factorial is not supported for given input type.
11
Releasing any resources in use.

Outra coisa que vale notar é que o código dentro da cláusula finally é executado para cada item na lista.

Considerações finais

Espero que este tutorial tenha ajudado a entender o tratamento de exceções no Python. Além disso, não hesite em ver o que temos disponível para venda e para estudo no marketplace e não hesite em fazer perguntas e dar seu feedback valioso usando o feed abaixo.

O tratamento correto de exceções pode ser muito útil em situações onde sair do programa depois que ele recebe uma entrada inesperada não é viável. Se você tiver quaisquer perguntas relacionadas ao tratamento de exceção no Python, por favor me informe nos comentários.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.