Exceção e classes de exceção

Em geral, uma exceção é qualquer condição incomum. A exceção geralmente indica erros, mas às vezes eles inserem intencionalmente no programa, em casos como encerrar um procedimento antecipadamente ou se recuperar de uma escassez de recursos. Existem várias exceções integradas, que indicam condições como leitura após o final de um arquivo ou divisão por zero. Podemos definir nossas próprias exceções, chamadas de exceção personalizada.

O tratamento de exceções permite que você lide com erros normalmente e faça algo significativo a respeito. O tratamento de exceções tem dois componentes: “arremessar” e “pegar”.

Identificação de exceção (erros)

Cada erro que ocorre no Python resulta em uma exceção que será uma condição de erro identificada por seu tipo de erro.

>>> #Exception
>>> 1/0
Traceback (most recent call last):
   File "<pyshell#2>", line 1, in <module>
      1/0
ZeroDivisionError: division by zero
>>>
>>> var = 20
>>> print(ver)
Traceback (most recent call last):
   File "<pyshell#5>", line 1, in <module>
      print(ver)
NameError: name 'ver' is not defined
>>> #Above as we have misspelled a variable name so we get an NameError.
>>>
>>> print('hello)

SyntaxError: EOL while scanning string literal
>>> #Above we have not closed the quote in a string, so we get SyntaxError.
>>>
>>> #Below we are asking for a key, that doen't exists.
>>> mydict = {}
>>> mydict['x']
Traceback (most recent call last):
   File "<pyshell#15>", line 1, in <module>
      mydict['x']
KeyError: 'x'
>>> #Above keyError
>>>
>>> #Below asking for a index that didn't exist in a list.
>>> mylist = [1,2,3,4]
>>> mylist[5]
Traceback (most recent call last):
   File "<pyshell#20>", line 1, in <module>
      mylist[5]
IndexError: list index out of range
>>> #Above, index out of range, raised IndexError.

Exceção de captura / captura

Quando algo incomum ocorre em seu programa e você deseja tratá-lo usando o mecanismo de exceção, você 'lança uma exceção'. As palavras-chave try e except são usadas para capturar exceções. Sempre que ocorre um erro em um bloco try, o Python procura um bloco exceto correspondente para tratá-lo. Se houver um, a execução salta para lá.

sintaxe

try:
   #write some code
   #that might throw some exception
except <ExceptionType>:
   # Exception handler, alert the user

O código dentro da cláusula try será executado instrução por instrução.

Se ocorrer uma exceção, o resto do bloco try será ignorado e a cláusula except será executada.

try:
   some statement here
except:
   exception handling

Vamos escrever um código para ver o que acontece quando você não usa nenhum mecanismo de tratamento de erros em seu programa.

number = int(input('Please enter the number between 1 & 10: '))
print('You have entered number',number)

O programa acima funcionará corretamente desde que o usuário insira um número, mas o que acontece se os usuários tentarem colocar algum outro tipo de dados (como uma string ou uma lista).

Please enter the number between 1 > 10: 'Hi'
Traceback (most recent call last):
   File "C:/Python/Python361/exception2.py", line 1, in <module>
      number = int(input('Please enter the number between 1 & 10: '))
ValueError: invalid literal for int() with base 10: "'Hi'"

Agora ValueError é um tipo de exceção. Vamos tentar reescrever o código acima com tratamento de exceção.

import sys

print('Previous code with exception handling')

try:
   number = int(input('Enter number between 1 > 10: '))

except(ValueError):
   print('Error..numbers only')
   sys.exit()

print('You have entered number: ',number)

Se executarmos o programa e inserirmos uma string (em vez de um número), podemos ver que obtemos um resultado diferente.

Previous code with exception handling
Enter number between 1 > 10: 'Hi'
Error..numbers only

Levantando exceções

Para levantar suas exceções de seus próprios métodos você precisa usar a palavra-chave raise como esta

raise ExceptionClass(‘Some Text Here’)

Vamos dar um exemplo

def enterAge(age):
   if age<0:
      raise ValueError('Only positive integers are allowed')
   if age % 2 ==0:
      print('Entered Age is even')
   else:
      print('Entered Age is odd')

try:
   num = int(input('Enter your age: '))
   enterAge(num)
except ValueError:
   print('Only positive integers are allowed')

Execute o programa e insira um número inteiro positivo.

Saída Esperada

Enter your age: 12
Entered Age is even

Mas quando tentamos inserir um número negativo, obtemos,

Saída Esperada

Enter your age: -2
Only positive integers are allowed

Criação de classe de exceção personalizada

Você pode criar uma classe de exceção personalizada Extending BaseException class ou subclasse de BaseException.

No diagrama acima, podemos ver a maioria das classes de exceção em extensões do Python da classe BaseException. Você pode derivar sua própria classe de exceção da classe BaseException ou de sua subclasse.

Crie um novo arquivo chamado NegativeNumberException.py e escreva o código a seguir.

class NegativeNumberException(RuntimeError):
   def __init__(self, age):
      super().__init__()
      self.age = age

O código acima cria uma nova classe de exceção chamada NegativeNumberException, que consiste apenas no construtor que chama o construtor da classe pai usando super () __ init __ () e define a idade.

Agora, para criar sua própria classe de exceção personalizada, escreverá algum código e importará a nova classe de exceção.

from NegativeNumberException import NegativeNumberException
def enterage(age):
   if age < 0:
      raise NegativeNumberException('Only positive integers are allowed')

   if age % 2 == 0:
      print('Age is Even')

   else:
      print('Age is Odd')

try:
   num = int(input('Enter your age: '))
   enterage(num)
except NegativeNumberException:
   print('Only positive integers are allowed')
except:
   print('Something is wrong')

Resultado

Enter your age: -2
Only positive integers are allowed

Outra maneira de criar uma classe de exceção personalizada.

class customException(Exception):
   def __init__(self, value):
      self.parameter = value

   def __str__(self):
      return repr(self.parameter)
try:
   raise customException('My Useful Error Message!')
except customException as instance:
   print('Caught: ' + instance.parameter)

Resultado

Caught: My Useful Error Message!

Hierarquia de exceção

A hierarquia de classes para exceções integradas é -

+-- SystemExit 
+-- KeyboardInterrupt 
+-- GeneratorExit 
+-- Exception 
+-- StopIteration 
+-- StopAsyncIteration 
+-- ArithmeticError 
| +-- FloatingPointError 
| +-- OverflowError 
| +-- ZeroDivisionError 
+-- AssertionError 
+-- AttributeError 
+-- BufferError 
+-- EOFError 
+-- ImportError 
+-- LookupError 
| +-- IndexError 
| +-- KeyError 
+-- MemoryError 
+-- NameError 
| +-- UnboundLocalError 
+-- OSError 
| +-- BlockingIOError 
| +-- ChildProcessError 
| +-- ConnectionError 
| | +-- BrokenPipeError 
| | +-- ConnectionAbortedError 
| | +-- ConnectionRefusedError 
| | +-- ConnectionResetError 
| +-- FileExistsError 
| +-- FileNotFoundError 
| +-- InterruptedError 
| +-- IsADirectoryError 
| +-- NotADirectoryError 
| +-- PermissionError 
| +-- ProcessLookupError 
| +-- TimeoutError 
+-- ReferenceError 
+-- RuntimeError 
| +-- NotImplementedError 
| +-- RecursionError 
+-- SyntaxError 
| +-- IndentationError
| +-- TabError 
+-- SystemError 
+-- TypeError 
+-- ValueError 
| +-- UnicodeError 
| +-- UnicodeDecodeError 
| +-- UnicodeEncodeError 
| +-- UnicodeTranslateError 
+-- Warning 
+-- DeprecationWarning 
+-- PendingDeprecationWarning 
+-- RuntimeWarning 
+-- SyntaxWarning 
+-- UserWarning 
+-- FutureWarning 
+-- ImportWarning 
+-- UnicodeWarning 
+-- BytesWarning 
+-- ResourceWarning