Klasy wyjątków i wyjątków

Ogólnie wyjątek stanowi każdy nietypowy stan. Wyjątek zwykle wskazuje na błędy, ale czasami celowo umieszcza je w programie, w przypadkach takich jak przedwczesne zakończenie procedury lub naprawa po niedoborze zasobów. Istnieje wiele wbudowanych wyjątków, które wskazują warunki, takie jak czytanie poza koniec pliku lub dzielenie przez zero. Możemy zdefiniować własne wyjątki zwane niestandardowymi wyjątkami.

Obsługa wyjątków pozwala z wdziękiem obsługiwać błędy i robić z nimi coś znaczącego. Obsługa wyjątków składa się z dwóch elementów: „rzucania” i „łapania”.

Identyfikowanie wyjątku (błędy)

Każdy błąd występujący w Pythonie powoduje wyjątek, który będzie stanowił warunek błędu identyfikowany przez jego typ błędu.

>>> #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.

Wyjątek łapania / wychwytywania

Kiedy w twoim programie wydarzy się coś niezwykłego i chcesz sobie z tym poradzić za pomocą mechanizmu wyjątków, „rzucasz wyjątek”. Słowa kluczowe try and except służą do wychwytywania wyjątków. Ilekroć wystąpi błąd w bloku try, Python szuka pasującego bloku oprócz tego, aby go obsłużyć. Jeśli istnieje, wskakuje tam egzekucja.

składnia

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

Kod w klauzuli try zostanie wykonany instrukcja po instrukcji.

Jeśli wystąpi wyjątek, pozostała część bloku try zostanie pominięta, a klauzula except zostanie wykonana.

try:
   some statement here
except:
   exception handling

Napiszmy trochę kodu, aby zobaczyć, co się stanie, gdy nie użyjesz żadnego mechanizmu obsługi błędów w swoim programie.

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

Powyższy program będzie działał poprawnie, dopóki użytkownik wprowadzi liczbę, ale co się stanie, jeśli użytkownicy spróbują umieścić inny typ danych (np. Ciąg znaków lub listę).

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'"

Teraz ValueError jest typem wyjątku. Spróbujmy przepisać powyższy kod z obsługą wyjątków.

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)

Jeśli uruchomimy program i wprowadzimy ciąg (zamiast liczby), zobaczymy, że otrzymujemy inny wynik.

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

Podnoszenie wyjątków

Aby zgłosić wyjątki z własnych metod, musisz użyć takiego słowa kluczowego

raise ExceptionClass(‘Some Text Here’)

Weźmy przykład

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')

Uruchom program i wprowadź dodatnią liczbę całkowitą.

Oczekiwany wynik

Enter your age: 12
Entered Age is even

Ale kiedy próbujemy wpisać liczbę ujemną, otrzymujemy

Oczekiwany wynik

Enter your age: -2
Only positive integers are allowed

Tworzenie niestandardowej klasy wyjątków

Możesz utworzyć niestandardową klasę wyjątków, rozszerzając klasę BaseException lub podklasę BaseException.

Z powyższego diagramu widzimy, że większość klas wyjątków w Pythonie pochodzi z klasy BaseException. Możesz wyprowadzić własną klasę wyjątków z klasy BaseException lub z jej podklasy.

Utwórz nowy plik o nazwie NegativeNumberException.py i napisz następujący kod.

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

Powyższy kod tworzy nową klasę wyjątków o nazwie NegativeNumberException, która składa się tylko z konstruktora, który wywołuje konstruktor klasy nadrzędnej za pomocą super () __ init __ () i ustawia wiek.

Teraz, aby utworzyć własną niestandardową klasę wyjątków, napiszesz kod i zaimportujesz nową klasę wyjątków.

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')

Wynik

Enter your age: -2
Only positive integers are allowed

Inny sposób tworzenia niestandardowej klasy Exception.

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)

Wynik

Caught: My Useful Error Message!

Hierarchia wyjątków

Hierarchia klas dla wbudowanych wyjątków to -

+-- 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