Tratamento de exceções Python

Resumo : neste tutorial, você aprende como lidar com exceções em Python da maneira certa usando a tryinstrução.

Introdução ao tratamento de exceções em Python

Para lidar com exceções, você usa a tryinstrução. A trydeclaração possui as seguintes cláusulas:

try:
    # code that you want to protect from exceptions
except <ExceptionType> as ex:
    # code that handle the exception
finally:
    # code that always execute whether the exception occurred or not
else:
    # code that excutes if try execute normally (an except clause must be present)Linguagem de código:  Python  ( python )

Vamos examinar a tryafirmação com mais detalhes.

tentar

Na trycláusula, você coloca o código que protege contra uma ou mais exceções potenciais. É uma boa prática manter o código o mais curto possível. Freqüentemente, você terá uma única instrução na trycláusula.

A trycláusula aparece exatamente uma vez na trydeclaração.

exceto

Na exceptcláusula, você coloca o código que trata um tipo de exceção específico. Uma tryinstrução pode ter zero ou mais exceptcláusulas. Normalmente, cada exceptcláusula trata diferentes tipos de exceção de maneiras específicas.

Em uma exceptcláusula, o as exé opcional. E <ExceptionType>também é opcional. No entanto, se você omitir o <ExceptionType> as ex, terá um manipulador de exceções simples.

Ao especificar tipos de exceção nas exceptcláusulas, você coloca as exceções mais específicas nas menos específicas, de cima para baixo.

Se você tiver a mesma lógica que lida com diferentes tipos de exceção, poderá agrupá-los em uma única exceptcláusula. Por exemplo:

try:
...
except <ExceptionType1> as ex:
    log(ex)
except <ExceptionType2> as ex:
    log(ex)Linguagem de código:  Python  ( python )

Tornar-se

try:
...
except (<ExceptionType1>, <ExceptionType2>) as ex:
    log(ex)Linguagem de código:  Python  ( python )

É importante observar que a exceptordem é importante porque o Python executará a primeira exceptcláusula cujo tipo de exceção corresponde à exceção ocorrida.

finalmente

A finallycláusula pode aparecer zero ou 1 vez em uma trydeclaração. A finallycláusula sempre é executada independentemente de uma exceção ter ocorrido ou não.

outro

A elsecláusula também aparece zero ou 1 vez. E a elsecláusula só é válida se a instrução try tiver pelo menos uma exceptcláusula.

Normalmente, você coloca o código que será executado se a trycláusula terminar normalmente.

Exemplo de tratamento de exceção Python

O seguinte define uma função que retorna o resultado de um número por outro:

def divide(a, b):
    return a / bLinguagem de código:  Python  ( python )

Se você passar 0 para o segundo argumento, receberá uma ZeroDivisionErrorexceção:

divide(10, 0)Linguagem de código:  Python  ( python )

Erro:

ZeroDivisionError: division by zeroLinguagem de código:  Python  ( python )

Para corrigir isso, você pode tratar a ZeroDivisionErrorexceção na divide()função da seguinte maneira:

def divide(a, b):
    try:
        return a / b
    except ZeroDivisionError as ex:
        return NoneLinguagem de código:  Python  ( python )

Neste exemplo, a divide()função retorna Nonese ZeroDivisionErrorocorrer:

def divide(a, b):
    try:
        return a / b
    except ZeroDivisionError as ex:
        return NoneLinguagem de código:  Python  ( python )

Ao usar a divide()função, você precisa verificar se o resultado é None:

result = divide(10, 0)

if result is not None:
    print('result:', result)
else:
    print('Invalid inputs')Linguagem de código:  Python  ( python )

Mas retornar Nonepode não ser o melhor porque outros podem avaliar acidentalmente o resultado na ifdeclaração assim:

result = divide(10, 0)

if result:
    print('result:', result)
else:
    print('Invalid inputs')Linguagem de código:  Python  ( python )

Neste caso, funciona. No entanto, não funcionará se o primeiro argumento for zero. Por exemplo:

result = divide(0, 10)

if result:
    print('result:', result)
else:
    print('Invalid inputs')Linguagem de código:  Python  ( python )

Uma abordagem melhor é gerar uma exceção ao chamador, caso a ZeroDivisionErrorexceção tenha ocorrido. Por exemplo:

def divide(a, b):
    try:
        return a / b
    except ZeroDivisionError as ex:
        raise ValueError('The second argument (b) must not be zero')Linguagem de código:  Python  ( python )

Neste exemplo, a divide()função gerará um erro se bfor zero. Para usar a divide()função, você precisa capturar a ValueErrorexceção:

def divide(a, b):
    try:
        return a / b
    except ZeroDivisionError as ex:
        raise ValueError('The second argument (b) must not be zero')


try:
    result = divide(10, 0)
except ValueError as e:
    print(e)
else:
    print('result:', result)Linguagem de código:  Python  ( python )

Saída:

The second argument (b) must not be zeroLinguagem de código:  Python  ( python )

É uma boa prática gerar uma exceção em vez de retornar Noneem casos especiais.

Exceto exemplo de pedido

Ao capturar uma exceção na cláusula except, você precisa colocar as exceções da mais específica para a menos específica em termos de hierarquia de exceções.

O seguinte mostra três classes de exceção: Exception, LookupErrore IndexError:

Se você capturar a exceção, será necessário colocá-las na seguinte ordem: IndexError, LookupErorr e Exception.

Por exemplo, o seguinte define uma lista de três strings e tenta acessar o quarto elemento:

colors = ['red', 'green', 'blue']
try:
    print(colors[3])
except IndexError as e:
    print(type(e), 'Index error')
except LookupError as e:
    print(type(e), 'Lookup error')Linguagem de código:  Python  ( python )

Emite o seguinte erro:

<class 'IndexError'> Index errorLinguagem de código:  Python  ( python )

O colors[3]acesso causa uma IndexErrorexceção. Porém, se você trocar as exceptcláusulas e capturar a LookupErrorprimeira e a IndexErrorsegunda assim:

colors = ['red', 'green', 'blue']
try:
    print(colors[3])
except LookupError as e:
    print(type(e), 'Lookup error')
except IndexError as e:
    print(type(e), 'Index error')Linguagem de código:  Python  ( python )

Saída:

<class 'IndexError'> Lookup errorLinguagem de código:  Python  ( python )

A exceção ainda é, IndexErrormas a mensagem a seguir é enganosa.

Manipuladores de exceção simples

Quando quiser capturar qualquer exceção, você pode usar os manipuladores de exceção simples. Um manipulador de exceção simples não especifica um tipo de exceção:

try:
    ...
except:
    ...Linguagem de código:  Python  ( python )

É equivalente ao seguinte:

try:
    ...
except BaseException:

    ...Linguagem de código:  Python  ( python )

Um manipulador de exceções simples capturará todas as exceções, incluindo as exceções SystemExit e KeyboardInterupt.

Uma simples exceção tornará mais difícil interromper um programa com Control-C e disfarçar outros programas.

Se você quiser capturar todas as exceções que sinalizam erros de programa, você pode usar except Exception:

try:
    ...
except Exception:
    ...Linguagem de código:  Python  ( python )

Na prática, você deve evitar o uso de manipuladores de exceção simples. Se você não conhece as exceções a serem capturadas, deixe a exceção ocorrer e então modifique o código para lidar com essas exceções.

Para obter informações de exceção de um manipulador de exceção simples, você usa a exc_info()função do sysmódulo.

A sys.exc_info()função retorna uma tupla que consiste em três valores:

  • typeé o tipo de exceção ocorrida. É uma subclasse do BaseException.
  • valueé a instância do tipo de exceção.
  • tracebacké um objeto que encapsula a pilha de chamadas no ponto onde ocorreu originalmente a exceção.

O exemplo a seguir usa a sys.exc_info()função para examinar a exceção quando uma string é dividida por um número:

import sys

try:
    '20' / 2
except:
    exc_info = sys.exc_info()
    print(exc_info)Linguagem de código:  Python  ( python )

Saída:

(<class 'TypeError'>, TypeError("unsupported operand type(s) for /: 'str' and 'int'"), <traceback object at 0x000001F19F42E700>)Linguagem de código:  Python  ( python )

A saída mostra que o código na cláusula try causa uma TypeErrorexceção. Portanto, você pode modificar o código para lidar com isso especificamente da seguinte maneira:

try:
    '20' / 2
except TypeError as e:
    print(e)Linguagem de código:  Python  ( python )

Saída:

unsupported operand type(s) for /: 'str' and 'int'Linguagem de código:  Python  ( python )

Resumo

  • Use a tryinstrução para lidar com exceção.
  • Coloque apenas o código mínimo que você deseja proteger de possíveis exceções na trycláusula.
  • Lide com exceções da mais específica para a menos específica em termos de tipos de exceção. A ordem das exceptcláusulas é importante.
  • O finalmente sempre é executado independentemente de as exceções terem ocorrido ou não.
  • A elsecláusula só é executada quando trytermina normalmente. A elsecláusula é válida somente se a tryinstrução tiver pelo menos uma exceptcláusula.
  • Evite usar manipuladores de exceção simples.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *