Exceções

As exceções ocorrem quando excepcional ocorrem situações no seu programa. Por exemplo, e se você estiver lendo um arquivo e o arquivo não existir? Ou se você o apagou acidentalmente quando o programa estava funcionando? Tais situações são tratadas usando exceções.

Da mesma forma, e se o seu programa tivesse algumas declarações inválidas? Isso é tratado por Python que levanta suas mãos e diz que há uma erro.

Erros

Considere um simples print chamada de função. E se nós falamos print como Print? Observe a capitalização. Neste caso, Python levanta um erro de sintaxe.

>>> Print("Hello World")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Print' is not defined
>>> print("Hello World")
Hello World

Observe que um NameError é gerado e também o local onde o erro foi detectado é impresso. É isso que um error handler por este erro.

Exceções

Nós vamos tentar para ler a entrada do usuário. Digite a primeira linha abaixo e aperte Enter. Quando seu computador solicitar a entrada, pressione [ctrl-d] em um Mac ou [ctrl-z] com o Windows e veja o que acontece. (Se você estiver usando o Windows e nenhuma das opções funciona, você pode tentar [ctrl-c] no prompt de comando para gerar um erro KeyboardInterrupt em vez disso).

>>> s = input('Enter something --> ')
Enter something --> Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
EOFError

Python levanta um erro chamado EOFError o que basicamente significa que encontrou um fim do arquivo símbolo (que é representado por ctrl-d) quando não esperava ver isso.

Manipulação de Exceções

Podemos lidar com exceções usando a try..except declaração. Nós, basicamente, colocamos nossas declarações usuais dentro do try-block e colocamos todos os nossos manipuladores de erros no bloco exceto.

Exemplo (salvar como exceptions_handle.py):

try:
    text = input('Enter something --> ')
except EOFError:
    print('Why did you do an EOF on me?')
except KeyboardInterrupt:
    print('You cancelled the operation.')
else:
    print('You entered {}'.format(text))

Saída:

# Press ctrl + d
$ python exceptions_handle.py
Enter something --> Why did you do an EOF on me?

# Press ctrl + c
$ python exceptions_handle.py
Enter something --> ^CYou cancelled the operation.

$ python exceptions_handle.py
Enter something --> No exceptions
You entered No exceptions

Como funciona

Colocamos todas as declarações que podem gerar exceções / erros dentro da try bloqueie e coloque os manipuladores para os erros / exceções apropriados no except cláusula / bloco. O except A cláusula pode lidar com um único erro ou exceção especificado, ou uma lista entre parênteses de erros / exceções. Se nenhum nome de erros ou exceções forem fornecidos, ele tratará todos erros e exceções.

Observe que deve haver pelo menos um except cláusula associada a cada try cláusula. Caso contrário, qual é o ponto de ter um bloco de tentativa?

Se qualquer erro ou exceção não for processado, é chamado o manipulador Python padrão que apenas interrompe a execução do programa e imprime uma mensagem de erro. Já vimos isso em ação acima.

Você também pode ter um else cláusula associada a umatry..except. A else cláusula é executada se nenhuma exceção ocorrer.

No próximo exemplo, também veremos como obter o objeto de exceção para que possamos recuperar informações adicionais.

Criando Exceções

Você pode levantar exceções usando o raise declaração fornecendo o nome do erro / exceção e do objeto de exceção a ser jogado.

O erro ou exceção que você pode aumentar deve ser uma classe que, direta ou indiretamente, deve ser uma classe derivada do Exception classe.

Exemplo (salvar como exceptions_raise.py):

class ShortInputException(Exception):
    '''A user-defined exception class.'''
    def __init__(self, length, atleast):
        Exception.__init__(self)
        self.length = length
        self.atleast = atleast

try:
    text = input('Enter something --> ')
    if len(text) < 3:
        raise ShortInputException(len(text), 3)
    # Other work can continue as usual here
except EOFError:
    print('Why did you do an EOF on me?')
except ShortInputException as ex:
    print(('ShortInputException: The input was ' +
           '{0} long, expected at least {1}')
          .format(ex.length, ex.atleast))
else:
    print('No exception was raised.')

Saída:

$ python exceptions_raise.py
Enter something --> a
ShortInputException: The input was 1 long, expected at least 3

$ python exceptions_raise.py
Enter something --> abc
No exception was raised.

Como funciona

Aqui, estamos criando nosso próprio tipo de exceção. Esse novo tipo de exceção é chamado ShortInputException. Tem dois campos - length qual é o comprimento da entrada dada, e atleast qual é o comprimento mínimo que o programa esperava.

Na except cláusula, mencionamos a classe de erro que será armazenada as o nome da variável para manter o objeto de erro / exceção correspondente. Isso é análogo a parâmetros e argumentos em uma chamada de função. Dentro deste particular except cláusula, usamos o length e atleast campos do objeto de exceção para imprimir uma mensagem apropriada para o usuário.

Tente ... Finalmente

Suponha que esteja lendo um arquivo no seu programa. Como você garante que o objeto do arquivo seja fechado corretamente se uma exceção foi ou não levantada? Isso pode ser feito usando o finally.

Salve este programa como exceptions_finally.py:

import sys
import time

f = None
try:
    f = open("poem.txt")
    # Our usual file-reading idiom
    while True:
        line = f.readline()
        if len(line) == 0:
            break
        print(line, end='')
        sys.stdout.flush()
        print("Press ctrl+c now")
        # To make sure it runs for a while
        time.sleep(2)
except IOError:
    print("Could not find file poem.txt")
except KeyboardInterrupt:
    print("!! You cancelled the reading from the file.")
finally:
    if f:
        f.close()
    print("(Cleaning up: Closed the file)")

Saída:

$ python exceptions_finally.py
Programming is fun
Press ctrl+c now
^C!! You cancelled the reading from the file.
(Cleaning up: Closed the file)

Como funciona

Nós fazemos o material usual de leitura de arquivos, mas nós arbitrariamente apresentamos o sono por 2 segundos depois de imprimir cada linha usando o time.sleep Funcione para que o programa seja lento (Python é muito rápido por natureza). Quando o programa ainda estiver em execução, pressione ctrl + c para interromper / cancelar o programa.

Observe que o KeyboardInterrupt A exceção é lançada e o programa é encerrado. No entanto, antes do programa sair, a cláusula finally é executada e o objeto do arquivo está sempre fechado.

Observe que uma variável atribuiu um valor de 0 ou None ou uma variável que é uma seqüência ou coleção vazia é considerada False por Python. É por isso que podemos usar if: f no código acima.

Observe também que usamos sys.stdout.flush() após print de modo que imprima na tela imediatamente.

A declaração com

Adquirir um recurso no try bloquear e posteriormente liberar o recurso no finally O bloco é um padrão comum. Por isso, há também um with declaração que permite que isso seja feito de maneira limpa:

Salvar como exceptions_using_with.py:

with open("poem.txt") as f:
    for line in f:
        print(line, end='')

Como funciona

O resultado deve ser o mesmo que o exemplo anterior. A diferença aqui é que estamos usando o open funcionar com o with declaração - deixamos o fechamento do arquivo a ser feito automaticamente por with open.

O que acontece nos bastidores é que existe um protocolo usado pelo with declaração. Obtém o objeto retornado pelo open declaração, vamos chamá-lo de "thefile" neste caso.

Ele sempre chama o thefile.__enter__ antes de iniciar o bloco de código abaixo e always chama thefile.__exit__ depois de terminar o bloco de código.

Então, o código que nós teríamos escrito em um finally bloco deve ser atendido automaticamente pelo __exit__ método. Isso é o que nos ajuda a evitar ter que usar explícito try..finally declarações repetidas.

Mais discussão sobre este tópico está além do alcance deste livro, por isso, consulte PEP 343 para uma explicação abrangente.

Resumo

Discutimos o uso do try..except e try..finally afirmações. Vimos como criar nossos próprios tipos de exceção e como aumentar as exceções também..

Em seguida, exploraremos a Biblioteca Padrão Python.