0%

⚠️ Kļūdu apstrāde

Kļūdu (izņēmumu) apstrāde nodrošina, ka programma turpina strādāt pat neparedzētu situāciju gadījumā. Python izmanto try/except/else/finally blokus.

python

try / except

Teksts
# Pamata try/except
try:
    skaitlis = int(input("Ievadi skaitli: "))
    rezultāts = 10 / skaitlis
    print(f"Rezultāts: {rezultāts}")
except ValueError:
    print("Lūdzu ievadi derīgu skaitli!")
except ZeroDivisionError:
    print("Nevar dalīt ar nulli!")

# Vairāki izņēmumi vienā except
try:
    x = int("abc")
except (ValueError, TypeError) as e:
    print(f"Kļūda: {e}")

# Sagūstīt jebkuru kļūdu (rezerves)
try:
    fails = open("neeksistē.txt")
except FileNotFoundError:
    print("Fails nav atrasts!")
except Exception as e:
    print(f"Negaidīta kļūda: {type(e).__name__}: {e}")

# as e – kļūdas ziņojums
try:
    saraksts = [1, 2, 3]
    print(saraksts[10])
except IndexError as e:
    print(f"Indekss ārpus robežām: {e}")
    # Indekss ārpus robežām: list index out of range

else un finally

Teksts
# else – izpildās, JA try nebija kļūdas
try:
    x = int("42")
except ValueError:
    print("Nav derīgs skaitlis")
else:
    print(f"Veiksmīgi pārveidots: {x}")   # Šī daļa izpildās
finally:
    print("Šis vienmēr izpildās")          # Arī pie kļūdas!

# finally – iztīrīšanai (resurs atbrīvošana)
fails = None
try:
    fails = open("data.txt", "r")
    saturs = fails.read()
    print(saturs)
except FileNotFoundError:
    print("Fails nav atrasts!")
finally:
    if fails:
        fails.close()  # Vienmēr aizveram!
    print("Funkcija beigusies")

# Labāks veids ar with (automātiska aizvēršana)
try:
    with open("data.txt", "r") as f:
        print(f.read())
except FileNotFoundError:
    print("Fails nav atrasts!")

Biežākie izņēmumu tipi

Teksts
# ValueError – nepareiza vērtība
int("abc")           # ValueError: invalid literal
float("xyz")         # ValueError

# TypeError – nepareizs tips
"2" + 2              # TypeError: can only concatenate str (not "int") to str
len(42)              # TypeError

# KeyError – vārdnīcas atslēga neeksistē
d = {"a": 1}
d["b"]               # KeyError: "b"
# Labojums: d.get("b") vai "b" in d

# IndexError – saraksta indekss ārpus robežām
saraksts = [1, 2, 3]
saraksts[10]         # IndexError: list index out of range

# AttributeError – atribūts neeksistē
n = None
n.upper()            # AttributeError: "NoneType" object has no attribute "upper"

# FileNotFoundError – fails neeksistē
open("nav_faila.txt")  # FileNotFoundError

# ZeroDivisionError
10 / 0               # ZeroDivisionError: division by zero

# NameError – mainīgais nav definēts
print(nedefinēts)    # NameError: name "nedefinēts" is not defined

# RecursionError – pārāk dziļa rekursija
def bezgala():
    return bezgala()
bezgala()            # RecursionError: maximum recursion depth exceeded

# ImportError / ModuleNotFoundError
import neeksistē     # ModuleNotFoundError: No module named "neeksistē"

# Izņēmumu hierarhija (daļa):
# BaseException
#   ├── SystemExit
#   ├── KeyboardInterrupt (Ctrl+C)
#   └── Exception
#         ├── ValueError
#         ├── TypeError
#         ├── AttributeError
#         ├── LookupError
#         │     ├── KeyError
#         │     └── IndexError
#         └── OSError
#               └── FileNotFoundError

raise – izvirzīt izņēmumu

Teksts
# Manuāli izvirzīt izņēmumu
def dalīt(a, b):
    if b == 0:
        raise ValueError("Dalītājs nedrīkst būt nulle!")
    return a / b

try:
    print(dalīt(10, 0))
except ValueError as e:
    print(f"Kļūda: {e}")   # Kļūda: Dalītājs nedrīkst būt nulle!

# Re-raise – aizvirzīt tālāk
def apstrādāt_failu(ceļš):
    try:
        with open(ceļš) as f:
            return f.read()
    except FileNotFoundError:
        print(f"Brīdinājums: {ceļš} nav atrasts")
        raise   # Izmet to pašu kļūdu tālāk

# Pārveidot vienu kļūdu par citu
try:
    vērtība = int("abc")
except ValueError as oriģinālā:
    raise RuntimeError("Datu apstrādes kļūda") from oriģinālā

Īpaši izņēmumu tipi

Teksts
# Izveidot savus izņēmumu tipus
class VeikalaKļūda(Exception):
    """Bāzes klase veikala kļūdām."""
    pass

class NaudaNavPietiekama(VeikalaKļūda):
    def __init__(self, vajadzīgā, pieejamā):
        self.vajadzīgā = vajadzīgā
        self.pieejamā = pieejamā
        super().__init__(
            f"Nepietiek naudas! Vajag {vajadzīgā}€, pieejami {pieejamā}€"
        )

class ProduktsPārdots(VeikalaKļūda):
    def __init__(self, produkts):
        super().__init__(f"Produkts '{produkts}' ir izpārdots!")

# Izmantošana
def pirkt(produkts, cena, maks):
    if cena > maks:
        raise NaudaNavPietiekama(cena, maks)

try:
    pirkt("klēpjdators", 1200, 500)
except NaudaNavPietiekama as e:
    print(e)
    print(f"Trūkst: {e.vajadzīgā - e.pieejamā}€")
except VeikalaKļūda as e:
    print(f"Vispārīga veikala kļūda: {e}")

assert un logging

🎉 Apsveicam!

Tu esi pabeidzis Python pamatu kursu! Tagad tu pārzini mainīgos, ciklus, funkcijas, OOP, failu darbu un kļūdu apstrādi. Nākamais solis – praksē rakstīt savus projektus!

Teksts
# assert – pārbaude izstrādes laikā
def rēķināt_vecumu(gads_dzimšanas):
    assert 1900 <= gads_dzimšanas <= 2025, f"Nereāls gads: {gads_dzimšanas}"
    return 2025 - gads_dzimšanas

print(rēķināt_vecumu(2000))  # 25
# rēķināt_vecumu(1800)  # AssertionError: Nereāls gads: 1800
# UZMANĪBU: assert var izslēgt ar python -O (optimizācija)!

# logging – profesionālais žurnalēšanas veids
import logging

# Konfigurēt
logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s – %(levelname)s – %(message)s",
    filename="lietotne.log"   # Var izlaist, lai rādītu konsolē
)

# Pieejamie līmeņi (augošā nopietnībā):
logging.debug("Detalizēta atkļūdošanas info")
logging.info("Viss darbojas normāli")
logging.warning("Kaut kas nav kā vajag, bet strādā")
logging.error("Kļūda – kaut kas neizdevās")
logging.critical("Kritiska kļūda – sistēma var apstāties")

# Izmantošana kodā
def apstrādāt_pasūtījumu(id_, daudzums):
    logging.info(f"Apstrādā pasūtījumu #{id_}")
    if daudzums <= 0:
        logging.error(f"Nepareizs daudzums: {daudzums}")
        raise ValueError(f"Daudzumam jābūt pozitīvam, saņemts: {daudzums}")
    logging.debug(f"Pasūtījums #{id_}: {daudzums} gab.")
    return True

try:
    apstrādāt_pasūtījumu(42, -5)
except ValueError as e:
    logging.exception(f"Pasūtījums neizdevās: {e}")  # Pievieno stack trace!