Sobes.tech
Middle

Python-da iç-içə istisnalar necə işləyir?

sobes.tech Süni İntellekt

AI-dan cavab

İç içe keçmiş istisnalar, həmçinin istisna zəncirləmə kimi də tanınır, yeni bir istisna baş verdikdə əvvəlki haqqında məlumatların saxlanmasına imkan verir. Bu, səhvlərin ayıklanması və səbəblərinin anlaşılmasında faydalıdır.

Python 3-də, varsayılan olaraq, except və ya finally bloklarında yeni istisna baş verdikdə, orijinal istisna avtomatik olaraq yeni ilə əlaqələndirilir.

Bu əlaqə, yeni istisnanın __cause__ atributunda saxlanılır.

Açıq əlaqələndirmə, raise from açar sözü istifadə edilərək həyata keçirilə bilər.

# Avtomatik əlaqələndirmə nümunəsi
def divide(a, b):
    try:
        return a / b
    except TypeError:
        # TypeError ilə işləyərkən başqa bir istisna baş verə bilər
        # Orijinal istisna (TypeError) yeni ilə əlaqələndiriləcək
        raise ValueError("Yanlış operand tipləri")

try:
    divide("a", 0)
except ValueError as e:
    # e.__cause__ TypeError-ı göstərəcək
    print(f"Xəta: {e}")
    if e.__cause__:
        print(f"Səbəb: {e.__cause__}")

print("-" * 20)

# Açıq əlaqələndirmə nümunəsi with raise from
class CustomError(Exception):
    pass

def tricky_function():
    try:
        # Sıfıra bölmə cəhdində ZeroDivisionError yaranır
        result = 1 / 0
    except ZeroDivisionError as original_exc:
        # Yeni istisna yaradın və onu orijinal ilə əlaqələndirin
        raise CustomError("Hesablama xətası") from original_exc

try:
    tricky_function()
except CustomError as e:
    # e.__cause__ ZeroDivisionError-ı göstərəcək
    print(f"Xəta: {e}")
    if e.__cause__:
        print(f"Səbəb: {e.__cause__}")

print("-" * 20)

# raise ... from None ilə əlaqələndirməni ləğv etmək
try:
    try:
        # Orijinal istisna
        raise ValueError("Əsas xəta")
    except ValueError:
        # ValueError ilə işləyərkən başqa bir istisna baş verir,
        # lakin əlaqələndirmə ləğv edilir
        raise TypeError("Yeni xəta") from None
except TypeError as e:
    # e.__cause__ burada None olacaq
    print(f"Xəta: {e}")
    if e.__cause__ is None:
        print("Səbəb göstərilməyib.")

raise açar sözü argumentsiz istifadə olunduqda, ən son baş verən istisnayı yenidən qaldırır.

# Yenidən istisna qaldırma nümunəsi
def process_data(data):
    try:
        # Burada nəsə səhv ola bilər
        if not data:
            raise ValueError("Məlumatlar yoxdur")
        print("Məlumatlar işlənib")
    except ValueError:
        print("ValueError tutdu")
        # Eyni istisnayı yenidən qaldır
        raise

try:
    process_data("")
except ValueError as e:
    print(f"Yenidən qaldırılan istisna: {e}")

İç içə keçmiş istisnalar xətaların izlənməsini daha oxunaqlı edir və problemin əsas səbəbini daha tez tapmağa kömək edir.