Sobes.tech
Middle

Kuidas töötavad sisemised erandid Pythonis?

sobes.tech AI

Vastus AI-lt

Sissetoodud erandid, mida nimetatakse ka erandite ahelaks või erandite sidumiseks, võimaldavad säilitada teavet eelneva erandi kohta, kui tekib uus. See on kasulik silumiseks ja vea põhjuste mõistmiseks.

Python 3 vaikimisi korral, kui erand tekib except või finally ploki sees, seostatakse algne erand automaatselt uuega.

Seda sidet hoitakse __cause__ atribuudis uue erandi puhul.

Selge sidumine saab toimuda võtmesõnaga raise from.

# Automaatse sidumise näide
def divide(a, b):
    try:
        return a / b
    except TypeError:
        # Kui tekib TypeError, võib tekkida teine erand
        # Algne erand (TypeError) seotakse uuega
        raise ValueError("Vale operandi tüüp")

try:
    divide("a", 0)
except ValueError as e:
    # e.__cause__ sisaldab siin TypeError
    print(f"Viga: {e}")
    if e.__cause__:
        print(f"Käivitatud: {e.__cause__}")

print("-" * 20)

# Näide otsese sidumisega kasutades raise from
class CustomError(Exception):
    pass

def tricky_function():
    try:
        # Nulliga jagamine, põhjustab ZeroDivisionError
        result = 1 / 0
    except ZeroDivisionError as original_exc:
        # Loome uue erandi ja seome selle algsega
        raise CustomError("Vigane arvutus") from original_exc

try:
    tricky_function()
except CustomError as e:
    # e.__cause__ sisaldab ZeroDivisionError
    print(f"Viga: {e}")
    if e.__cause__:
        print(f"Käivitatud: {e.__cause__}")

print("-" * 20)

# Sidumine raise ... from None abil
try:
    try:
        # Algne erand
        raise ValueError("Algne viga")
    except ValueError:
        # Kui tekib teine erand, sidumine on keelatud
        raise TypeError("Uus viga") from None
except TypeError as e:
    # e.__cause__ on siin None
    print(f"Viga: {e}")
    if e.__cause__ is None:
        print("Põhjus pole näidatud.")

Võtmesõna raise ilma argumentideta uuesti esile kutsuma viimast erandit.

# Näide erandi uuesti esilekutsumisest
def process_data(data):
    try:
        # Oletame, et siin võib midagi valesti minna
        if not data:
            raise ValueError("Andmed puuduvad")
        print("Andmed töödeldud")
    except ValueError:
        print("Kaaperdati ValueError")
        # Uuesti esilekutsume sama erandi
        raise

try:
    process_data("")
except ValueError as e:
    print(f"Kaaperdati uuesti esilekutsutud erand: {e}")

Sissetoodud erandid parandavad vigade jälgimise loetavust ja aitavad kiiremini tuvastada probleemi algpõhjust.