Sobes.tech
Middle

Kā darbojas iekļautās izņēmumi Python?

sobes.tech AI

Atbilde no AI

Iekļautie izņēmumi, arī pazīstami kā izņēmumu ķēdēšana vai saistība ar izņēmumiem, ļauj saglabāt informāciju par iepriekšējo izņēmumu, kad rodas jauns. Tas ir noderīgi atkļūdošanai un kļūdas cēloņa izpratnei.

Python 3 noklusējuma režīmā, ja izņēmums rodas iekšā except vai finally bloka, sākotnējais izņēmums automātiski tiek saistīts ar jauno.

Šī saite tiek glabāta __cause__ atribūtā jaunajam izņēmumam.

Pārdomāta saistība var tikt veikta ar atslēgvārdu raise from.

# Automātiskas saistības piemērs
def divide(a, b):
    try:
        return a / b
    except TypeError:
        # Laikā, kad tiek apstrādāts TypeError, var rasties cits izņēmums
        # Oriģinālais izņēmums (TypeError) tiks saistīts ar jauno
        raise ValueError("Nepareiza operandu tips")

try:
    divide("a", 0)
except ValueError as e:
    # e.__cause__ šeit saturēs TypeError
    print(f"Radās kļūda: {e}")
    if e.__cause__:
        print(f"Izsaukts no: {e.__cause__}")

print("-" * 20)

# Piemērs ar tiešu saistību ar raise from
class CustomError(Exception):
    pass

def tricky_function():
    try:
        # Mēģinājums dalīt ar nulli, izraisa ZeroDivisionError
        result = 1 / 0
    except ZeroDivisionError as original_exc:
        # Izveido jaunu izņēmumu un sasaista to ar oriģinālo
        raise CustomError("Kļūda aprēķinā") from original_exc

try:
    tricky_function()
except CustomError as e:
    # e.__cause__ šeit saturēs ZeroDivisionError
    print(f"Radās kļūda: {e}")
    if e.__cause__:
        print(f"Izsaukts no: {e.__cause__}")

print("-" * 20)

# Saistības ar raise ... from None tiek slēptas
try:
    try:
        # Sākotnējais izņēmums
        raise ValueError("Sākotnējā kļūda")
    except ValueError:
        # Apstrādes laikā rodas cits izņēmums,
        # bet saistība tiek slēpta
        raise TypeError("Jauna kļūda") from None
except TypeError as e:
    # e.__cause__ šeit būs None
    print(f"Radās kļūda: {e}")
    if e.__cause__ is None:
        print("Iemesls nav norādīts.")

Atslēgvārds raise bez argumentiem atkārtoti izraisa pēdējo izņēmumu.

# Piemērs ar izņēmuma atkārtotu izsaukšanu
def process_data(data):
    try:
        # Pieņemams, ka šeit kaut kas var noiet greizi
        if not data:
            raise ValueError("Trūkst dati")
        print("Dati apstrādāti")
    except ValueError:
        print("Noķerts ValueError")
        # Atkārtoti izsauc to pašu izņēmumu
        raise

try:
    process_data("")
except ValueError as e:
    print(f"Noķerts atkārtoti izsaukts izņēmums: {e}")

Iekļautie izņēmumi uzlabo kļūdu izsekošanas lasāmību un palīdz ātrāk lokalizēt problēmas cēloni.