CodeGym /Corsi /Python SELF IT /Creazione di una propria eccezione

Creazione di una propria eccezione

Python SELF IT
Livello 18 , Lezione 1
Disponibile

7.1 Creazione di eccezioni personalizzate

A volte le eccezioni standard di Python non soddisfano completamente le esigenze della tua applicazione. In questi casi, puoi creare le tue eccezioni personalizzate, ereditandole dalla classe di base Exception o da qualsiasi altra classe di eccezioni appropriata.

Fondamenti della creazione di eccezioni personalizzate

Creare un'eccezione personalizzata significa definire una nuova classe ereditata dalla classe di base Exception. Puoi aggiungere i tuoi metodi e attributi per fornire informazioni aggiuntive sull'errore.

Esempio di creazione di una semplice eccezione personalizzata

Passo 1: Definizione di un'eccezione personalizzata


class MyCustomError(Exception):
    """Classe per un'eccezione personalizzata."""
    pass
        

Passo 2: Utilizzo dell'eccezione personalizzata


def check_value(value):
    if value < 0:
        raise MyCustomError("Il valore non deve essere inferiore a zero")
            
try:
    check_value(-1)
except MyCustomError as e:
    print(f"Si è verificata un'eccezione personalizzata: {e}")
            

È tutto molto semplice. È importante che la tua eccezione erediti dalla classe Exception o da uno dei suoi discendenti.

7.2 Creazione di un'eccezione con attributi aggiuntivi

Puoi aggiungere attributi e metodi alla tua classe di eccezione per trasmettere informazioni aggiuntive sull'errore verificatosi.

Esempio:


class NegativeValueError( Exception ):
    """Classe per un'eccezione personalizzata quando il valore è negativo."""
    def __init__(self, value, message = "Il valore non deve essere inferiore a zero"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

Utilizzo dell'eccezione con attributi aggiuntivi


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)

try:
    check_value(-1)
except NegativeValueError as e:
    print(f"Si è verificata un'eccezione personalizzata: {e}")

La nostra eccezione è una classe ereditata dalla classe Exception. Pertanto, puoi fare con essa tutto ciò che puoi fare con qualsiasi altra classe: aggiungere campi, metodi, parametri del costruttore, ecc.

Tutto per la tua comodità e quella dei programmatori che intercetteranno le tue eccezioni.

7.3 Creazione di gerarchie di eccezioni personalizzate

Per applicazioni più complesse, è utile creare gerarchie di eccezioni personalizzate. Questo permette di raggruppare eccezioni correlate e semplifica la loro gestione.

Esempio:


class ApplicationError(Exception):
    """Classe base per tutte le eccezioni dell'applicazione."""
    pass

class NegativeValueError(ApplicationError):
    """Classe per un'eccezione personalizzata quando il valore è negativo."""
    def __init__(self, value, message="Il valore non deve essere inferiore a zero"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

class ValueTooLargeError(ApplicationError):
    """Classe per un'eccezione personalizzata quando il valore è troppo grande."""
    def __init__(self, value, message="Valore troppo grande"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

Utilizzo della gerarchia di eccezioni personalizzate


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)

try:
    check_value(150)
except NegativeValueError as e:
    print(f"Si è verificata un'eccezione: {e}")
except ValueTooLargeError as e:
    print(f"Si è verificata un'eccezione: {e}")
except ApplicationError as e:
    print(f"Eccezione generale dell'applicazione: {e}")

7.4 Ordine di cattura delle eccezioni

Quando si catturano eccezioni, specialmente da una stessa gerarchia, è importante indicarne l'ordine corretto. Anche se il codice all'interno dei blocchi except non viene mai eseguito simultaneamente, la classe base dell'eccezione può catturare eccezioni di tutte le classi figlie.

Ad esempio, il codice:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
    
try:
    check_value(150)
except ApplicationError as e: # catturerà eccezioni del tipo ApplicationError e tutte le sue sottoclassi
    print(f"Eccezione generale dell'applicazione: {e}")

Nel blocco except, verranno catturate eccezioni del tipo ApplicationError e di tutte le sue classi figlie.

E poiché tutte le eccezioni sono discendenti della classe Exception, tale codice catturerà tutte le eccezioni:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
    
try:
    check_value(150)
except Exception as e:
    print(f"Cattura di tutte le eccezioni: {e}")
except ApplicationError as e: # Questo codice non verrà mai eseguito
    print(f"Eccezione generale dell'applicazione: {e}")

La cattura delle eccezioni nel blocco except ApplicationError non avverrà mai, poiché il blocco except Exception catturerà tutte le eccezioni di tipo Exception e qualsiasi suo discendente.

Soluzione

Pertanto, è consuetudine catturare le eccezioni in ordine inverso rispetto all'ereditarietà: più il classe è vicina alla classe Exception, più è bassa.

Esempio:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
        
try:
    check_value(150)
except NegativeValueError as e:
    print(f"Si è verificata un'eccezione: {e}")
except ApplicationError as e:
    print(f"Eccezione generale dell'applicazione: {e}")
except Exception as e:
    print(f"Cattura di tutte le eccezioni: {e}")

In questo esempio, i blocchi except sono disposti in un ordine che corrisponde alla loro gerarchia di ereditarietà: prima vengono intercettate le eccezioni più specifiche, come NegativeValueError, poi quelle più generali, come ApplicationError. Questo permette di gestire correttamente le eccezioni ed evitare situazioni in cui un gestore più generale cattura un'eccezione prima che i blocchi except più specializzati possano gestirla.

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION