CodeGym /Kursy /Python SELF PL /Tworzenie własnego wyjątku

Tworzenie własnego wyjątku

Python SELF PL
Poziom 18 , Lekcja 1
Dostępny

7.1 Tworzenie niestandardowych wyjątków

Czasami standardowe wyjątki w Pythonie nie spełniają w pełni potrzeb twojej aplikacji. W takich sytuacjach możesz stworzyć własne wyjątki, dziedzicząc je z klasy bazowej Exception lub jakiejkolwiek innej odpowiedniej klasy wyjątków.

Podstawy tworzenia niestandardowych wyjątków

Tworzenie niestandardowego wyjątku polega na zdefiniowaniu nowej klasy, która dziedziczy po klasie bazowej Exception. Możesz dodać własne metody i atrybuty do swojej klasy wyjątków, aby dostarczyć dodatkowe informacje o błędzie.

Przykład tworzenia prostego niestandardowego wyjątku

Krok 1: Definiowanie niestandardowego wyjątku


class MyCustomError(Exception):
    """Klasa dla niestandardowego wyjątku."""
    pass
        

Krok 2: Użycie niestandardowego wyjątku


def check_value(value):
    if value < 0:
        raise MyCustomError("Wartość nie powinna być mniejsza od zera")
            
try:
    check_value(-1)
except MyCustomError as e:
    print(f"Zdarzył się niestandardowy wyjątek: {e}")
            

To bardzo proste. Najważniejsze, aby twój wyjątek dziedziczył po klasie Exception lub jednym z jej potomków.

7.2 Tworzenie wyjątku z dodatkowymi atrybutami

Możesz dodawać atrybuty i metody do swojej klasy wyjątków, aby przekazać dodatkowe informacje o powstałym błędzie.

Przykład:


class NegativeValueError( Exception ):
    """Klasa dla niestandardowego wyjątku przy ujemnej wartości."""
    def __init__(self, value, message = "Wartość nie powinna być mniejsza od zera"):
        self.value = value
        self.message = message
        super().__init__(self.message)

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

Użycie wyjątku z dodatkowymi atrybutami


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

try:
    check_value(-1)
except NegativeValueError as e:
    print(f"Zdarzył się niestandardowy wyjątek: {e}")

Nasz wyjątek to klasa, która dziedziczy po klasie Exception. Dlatego możesz z nim zrobić wszystko to, co z każdą inną klasą: dodawać pola, metody, parametry konstruktora itp.

Wszystko dla twojej wygody i wygody programistów, którzy będą przechwytywać twoje wyjątki.

7.3 Tworzenie hierarchii niestandardowych wyjątków

Dla bardziej zaawansowanych aplikacji warto tworzyć hierarchie niestandardowych wyjątków. Pozwala to grupować powiązane wyjątki i ułatwia ich obsługę.

Przykład:


class ApplicationError(Exception):
    """Klasa bazowa dla wszystkich wyjątków aplikacji."""
    pass

class NegativeValueError(ApplicationError):
    """Klasa dla niestandardowego wyjątku przy ujemnej wartości."""
    def __init__(self, value, message="Wartość nie powinna być mniejsza od zera"):
        self.value = value
        self.message = message
        super().__init__(self.message)

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

class ValueTooLargeError(ApplicationError):
    """Klasa dla niestandardowego wyjątku przy zbyt dużej wartości."""
    def __init__(self, value, message="Wartość jest za duża"):
        self.value = value
        self.message = message
        super().__init__(self.message)

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

Użycie hierarchii niestandardowych wyjątków


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"Zdarzył się wyjątek: {e}")
except ValueTooLargeError as e:
    print(f"Zdarzył się wyjątek: {e}")
except ApplicationError as e:
    print(f"Ogólny wyjątek aplikacji: {e}")

7.4 Kolejność przechwytywania wyjątków

Podczas przechwytywania wyjątków, zwłaszcza z jednej hierarchii, ważne jest, aby ustawić je w odpowiedniej kolejności. I chociaż kod w blokach except nigdy nie jest wykonywany jednocześnie, chodzi o to, że klasa bazowa wyjątku jest w stanie przechwycić wyjątki wszystkich klas potomnych.

Na przykład kod:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
    
try:
    check_value(150)
except ApplicationError as e: # przechwyci wyjątki typu ApplicationError i wszystkich jego potomków
    print(f"Ogólny wyjątek aplikacji: {e}")

W bloku except zostaną przechwycone wyjątki typu ApplicationError i wszystkich jego klas potomnych.

A ponieważ wszystkie wyjątki są potomkami klasy Exception, taki kod przechwyci w zasadzie wszystkie wyjątki:


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"Przechwycenie wszystkich wyjątków: {e}")
except ApplicationError as e: # Ten kod nigdy się nie wykona
    print(f"Ogólny wyjątek aplikacji: {e}")

Przechwytywanie wyjątków w bloku except ApplicationError nigdy nie nastąpi, ponieważ blok except Exception przechwyci w zasadzie wszystkie wyjątki typu Exception i jego potomków.

Rozwiązanie

Dlatego przechwytywanie wyjątków odbywa się w kolejności odwrotnej do dziedziczenia: im bliżej klasa do klasy Exception, tym niżej.

Przykład:


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"Zdarzył się wyjątek: {e}")
except ApplicationError as e:
    print(f"Ogólny wyjątek aplikacji: {e}")
except Exception as e:
    print(f"Przechwycenie wszystkich wyjątków: {e}")

W tym przykładzie bloki except są ułożone w kolejności, która odpowiada ich hierarchii dziedziczenia: najpierw przechwytywane są bardziej specyficzne wyjątki, takie jak NegativeValueError, a następnie bardziej ogólne, takie jak ApplicationError. To pozwala poprawnie obsłużyć wyjątki i unikać sytuacji, w której bardziej ogólny handler przechwyci wyjątek zanim zrobią to bardziej specjalistyczne bloki except.

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