Eccezioni e classi di eccezione
In generale, un'eccezione è una condizione insolita. L'eccezione di solito indica errori, ma a volte vengono inseriti intenzionalmente nel programma, in casi come l'interruzione anticipata di una procedura o il ripristino da una carenza di risorse. Esistono numerose eccezioni integrate, che indicano condizioni come la lettura oltre la fine di un file o la divisione per zero. Possiamo definire le nostre eccezioni chiamate eccezioni personalizzate.
La gestione delle eccezioni consente di gestire gli errori con garbo e di fare qualcosa di significativo al riguardo. La gestione delle eccezioni ha due componenti: "lancio" e "cattura".
Identificazione dell'eccezione (errori)
Ogni errore che si verifica in Python risulta un'eccezione che sarà una condizione di errore identificata dal suo tipo di errore.
>>> #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.
Eccezione cattura / cattura
Quando si verifica qualcosa di insolito nel tuo programma e desideri gestirlo utilizzando il meccanismo delle eccezioni, "lanci un'eccezione". Le parole chiave try e tranne vengono utilizzate per rilevare le eccezioni. Ogni volta che si verifica un errore all'interno di un blocco try, Python cerca un blocco eccetto corrispondente per gestirlo. Se ce n'è uno, l'esecuzione salta lì.
sintassi
try:
#write some code
#that might throw some exception
except <ExceptionType>:
# Exception handler, alert the user
Il codice all'interno della clausola try verrà eseguito istruzione per istruzione.
Se si verifica un'eccezione, il resto del blocco try verrà ignorato e verrà eseguita la clausola tranne.
try:
some statement here
except:
exception handling
Scriviamo un po 'di codice per vedere cosa succede quando non usi alcun meccanismo di gestione degli errori nel tuo programma.
number = int(input('Please enter the number between 1 & 10: '))
print('You have entered number',number)
Il programma sopra funzionerà correttamente fintanto che l'utente inserisce un numero, ma cosa succede se gli utenti cercano di inserire un altro tipo di dati (come una stringa o un elenco).
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'"
Ora ValueError è un tipo di eccezione. Proviamo a riscrivere il codice precedente con la gestione delle eccezioni.
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 eseguiamo il programma e inseriamo una stringa (invece di un numero), possiamo vedere che otteniamo un risultato diverso.
Previous code with exception handling
Enter number between 1 > 10: 'Hi'
Error..numbers only
Sollevare eccezioni
Per aumentare le tue eccezioni dai tuoi metodi devi usare la parola chiave raise come questa
raise ExceptionClass(‘Some Text Here’)
Facciamo un esempio
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')
Esegui il programma e inserisci un numero intero positivo.
Uscita prevista
Enter your age: 12
Entered Age is even
Ma quando proviamo a inserire un numero negativo otteniamo,
Uscita prevista
Enter your age: -2
Only positive integers are allowed
Creazione di una classe di eccezione personalizzata
È possibile creare una classe di eccezione personalizzata estendendo la classe BaseException o una sottoclasse di BaseException.
Dal diagramma sopra possiamo vedere la maggior parte delle classi di eccezione in Python che si estende dalla classe BaseException. È possibile derivare la propria classe di eccezione dalla classe BaseException o dalla sua sottoclasse.
Crea un nuovo file chiamato NegativeNumberException.py e scrivi il codice seguente.
class NegativeNumberException(RuntimeError):
def __init__(self, age):
super().__init__()
self.age = age
Il codice precedente crea una nuova classe di eccezione denominata NegativeNumberException, che consiste solo nel costruttore che chiama il costruttore della classe genitore usando super () __ init __ () e imposta l'età.
Ora per creare la tua classe di eccezione personalizzata, scriverà del codice e importerà la nuova classe di eccezione.
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')
Produzione
Enter your age: -2
Only positive integers are allowed
Un altro modo per creare una classe di eccezione personalizzata.
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)
Produzione
Caught: My Useful Error Message!
Gerarchia delle eccezioni
La gerarchia di classi per le eccezioni integrate è:
+-- 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