14-bo‘lim

Xatoliklar va istisnolar

Xato turlari, try/except/else/finally konstruksiyasi, raise bilan xato ko'tarish va o'z istisno klassingizni yaratish.

🕑 13 daqiqa o‘qish 📄 544 so‘z 👁 5 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Xatolarning uch turi
  2. Eng ko'p uchraydigan istisnolar
  3. try ... except
  4. Bir nechta istisnoni birga ushlash
  5. else va finally
  6. Xato haqida ma'lumot olish
  7. raise - xatoni o'zingiz ko'tarish
  8. O'z istisno klassingiz
  9. Xavfsiz kiritish funksiyasi
  10. Xatolarni jurnalga yozish
  11. Amaliy misol: ishonchli fayl o'quvchi
  12. Xulosa

Xatosiz dastur bo'lmaydi. Yaxshi dastur xatolardan qochmaydi - ularni to'g'ri boshqaradi.

Xatolarning uch turi #

1. Sintaksis xatosi Kod umuman ishga tushmaydi if x = 5: 2. Ishlash xatosi Dastur ishga tushadi, lekin to'xtab qoladi 10 / 0 3. Mantiqiy xato Dastur ishlaydi, lekin natija noto'g'ri ortacha = jami * n
Eng xavflisi - uchinchisi, chunki Python u haqda ogohlantirmaydi

Eng ko'p uchraydigan istisnolar #

IstisnoQachon yuz beradiMisol
ValueErrorQiymat noto'g'ri turdaint("salom")
TypeErrorTurlar mos kelmadi"5" + 5
ZeroDivisionErrorNolga bo'lish10 / 0
IndexErrorIndeks chegaradan tashqarida[1,2][5]
KeyErrorLug'atda kalit yo'q{"a":1}["b"]
FileNotFoundErrorFayl topilmadiopen("yoq.txt")
AttributeErrorObyektda bunday metod yo'q"matn".append()
NameErrorO'zgaruvchi e'lon qilinmaganprint(mavjudmas)
ImportErrorModul topilmadiimport mavjudmas
PermissionErrorFaylga ruxsat yo'qTizim fayliga yozish

try ... except #

Python
try:
    son = int(input("Son kiriting: "))
    natija = 100 / son
    print(f"Natija: {natija}")
except ValueError:
    print("Xato: faqat son kiriting!")
except ZeroDivisionError:
    print("Xato: nolga bo'lib bo'lmaydi!")
Natija
Son kiriting: salom
Xato: faqat son kiriting!
Natija
Son kiriting: 0
Xato: nolga bo'lib bo'lmaydi!
Natija
Son kiriting: 4
Natija: 25.0

Bir nechta istisnoni birga ushlash #

Python
try:
    qiymat = int(input("Son: "))
    print(10 / qiymat)
except (ValueError, ZeroDivisionError) as xato:
    print(f"Kiritishda muammo: {xato}")
Natija
Son: 0
Kiritishda muammo: division by zero
Bo'sh except yozmang
Python
try:
    xavfli_amal()
except:                     # YOMON!
    pass

Bu barcha xatolarni, jumladan Ctrl + C bosilganini ham "yutib yuboradi". Natijada dastur qotib qoladi va nima bo'layotganini bilib bo'lmaydi.

To'g'ri usul - aniq istisnoni ko'rsatish:

Python
try:
    xavfli_amal()
except ValueError as xato:
    print(f"Qiymat xatosi: {xato}")

else va finally #

Python
try:
    fayl = open("malumot.txt", "r", encoding="utf-8")
    mazmun = fayl.read()
except FileNotFoundError:
    print("Fayl topilmadi!")
else:
    # xato bo'lmaganda bajariladi
    print(f"Fayl o'qildi: {len(mazmun)} belgi")
    fayl.close()
finally:
    # HAR DOIM bajariladi
    print("Amal tugadi.")
Natija
Fayl topilmadi!
Amal tugadi.
BlokQachon bajariladi
tryHar doim (birinchi)
exceptFaqat mos xato yuz berganda
elseFaqat hech qanday xato bo'lmaganda
finallyHar doim, xato bo'lsa ham, bo'lmasa ham
finally nima uchun kerak?

Resurslarni tozalash uchun: faylni yopish, ma'lumotlar bazasi ulanishini uzish, vaqtinchalik fayllarni o'chirish. Bu amallar dastur qanday tugashidan qat'i nazar bajarilishi kerak.

Xato haqida ma'lumot olish #

Python
try:
    sonlar = [1, 2, 3]
    print(sonlar[10])
except IndexError as xato:
    print(f"Xato turi:  {type(xato).__name__}")
    print(f"Xabar:      {xato}")
Natija
Xato turi:  IndexError
Xabar:      list index out of range

raise - xatoni o'zingiz ko'tarish #

Python
def yosh_tekshir(yosh):
    if not isinstance(yosh, int):
        raise TypeError("Yosh butun son bo'lishi kerak")
    if yosh < 0:
        raise ValueError("Yosh manfiy bo'lishi mumkin emas")
    if yosh > 150:
        raise ValueError("Yosh 150 dan katta bo'lishi mumkin emas")
    return f"Yosh qabul qilindi: {yosh}"


print(yosh_tekshir(25))

try:
    yosh_tekshir(-5)
except ValueError as xato:
    print(f"Tekshiruv muvaffaqiyatsiz: {xato}")
Natija
Yosh qabul qilindi: 25
Tekshiruv muvaffaqiyatsiz: Yosh manfiy bo'lishi mumkin emas
Nima uchun xato ko'tarish kerak?

Funksiya noto'g'ri ma'lumot olganda None qaytarish yoki print qilish o'rniga xato ko'tarishi kerak. Shunda funksiyani chaqirgan kod muammoni sezadi va uni qanday hal qilishni o'zi hal qiladi. Bu "erta va baland ovozda ishdan chiq" (fail fast) tamoyili.

O'z istisno klassingiz #

Katta loyihalarda o'z xato turlaringizni yaratish qulay:

Python
class HisobXatosi(Exception):
    """Bank hisobi bilan bog'liq xatolar uchun asosiy klass."""
    pass


class MablagYetarliEmas(HisobXatosi):
    """Balansda yetarli mablag' bo'lmaganda ko'tariladi."""

    def __init__(self, talab_qilingan, mavjud):
        self.talab_qilingan = talab_qilingan
        self.mavjud = mavjud
        self.yetishmaydi = talab_qilingan - mavjud
        super().__init__(
            f"Mablag' yetarli emas: {yetishmaydi_matn(self.yetishmaydi)} kerak"
        )


def yetishmaydi_matn(summa):
    return f"{summa:,} so'm"


def pul_yechish(balans, summa):
    if summa > balans:
        raise MablagYetarliEmas(summa, balans)
    return balans - summa


try:
    yangi_balans = pul_yechish(500_000, 800_000)
except MablagYetarliEmas as xato:
    print(f"Amal bajarilmadi: {xato}")
    print(f"Yetishmayotgan summa: {xato.yetishmaydi:,} so'm")
Natija
Amal bajarilmadi: Mablag' yetarli emas: 300,000 so'm kerak
Yetishmayotgan summa: 300,000 so'm

Xavfsiz kiritish funksiyasi #

Bu shablon deyarli har bir dasturda kerak bo'ladi:

Python
def son_sora(xabar: str, eng_kam: int = None, eng_kop: int = None) -> int:
    """Foydalanuvchidan to'g'ri son kiritilgunicha so'raydi."""
    while True:
        try:
            qiymat = int(input(xabar))
        except ValueError:
            print("  ! Faqat butun son kiriting.")
            continue

        if eng_kam is not None and qiymat < eng_kam:
            print(f"  ! Qiymat {eng_kam} dan kichik bo'lmasin.")
            continue
        if eng_kop is not None and qiymat > eng_kop:
            print(f"  ! Qiymat {eng_kop} dan katta bo'lmasin.")
            continue

        return qiymat


yosh = son_sora("Yoshingiz: ", eng_kam=1, eng_kop=120)
print(f"Rahmat! Sizga {yosh} yosh.")
Natija
Yoshingiz: yigirma
  ! Faqat butun son kiriting.
Yoshingiz: 200
  ! Qiymat 120 dan katta bo'lmasin.
Yoshingiz: 22
Rahmat! Sizga 22 yosh.

Xatolarni jurnalga yozish #

Real dasturlarda xatolarni print qilish emas, faylga yozish kerak:

Python
import logging

logging.basicConfig(
    filename="xatolar.log",
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    encoding="utf-8",
)

def bolish(bolinuvchi, boluvchi):
    try:
        natija = bolinuvchi / boluvchi
    except ZeroDivisionError:
        logging.error(f"Nolga bo'lishga urinish: {bolinuvchi} / {boluvchi}")
        return None
    else:
        logging.info(f"Muvaffaqiyatli: {bolinuvchi} / {boluvchi} = {natija}")
        return natija


print(bolish(10, 2))
print(bolish(10, 0))
Natija
5.0
None

xatolar.log fayli mazmuni:

Natija
2026-09-08 14:42:03 [INFO] Muvaffaqiyatli: 10 / 2 = 5.0
2026-09-08 14:42:03 [ERROR] Nolga bo'lishga urinish: 10 / 0
DarajaQachon ishlatiladi
DEBUGNosozlikni tuzatish uchun tafsilotlar
INFOOddiy ish jarayoni haqida xabar
WARNINGMuammo bo'lishi mumkin, lekin ishlayapti
ERRORAmal bajarilmadi
CRITICALDastur to'xtash arafasida

Amaliy misol: ishonchli fayl o'quvchi #

Python
# ============================================
# Xatolarga chidamli CSV o'quvchi
# ============================================

import csv
from pathlib import Path


def csv_oqish(yol: str) -> list:
    """CSV faylni xavfsiz o'qiydi va lug'atlar ro'yxatini qaytaradi."""
    fayl_yoli = Path(yol)

    try:
        with open(fayl_yoli, "r", encoding="utf-8") as fayl:
            return list(csv.DictReader(fayl))

    except FileNotFoundError:
        print(f"  [XATO] Fayl topilmadi: {fayl_yoli}")
        return []
    except PermissionError:
        print(f"  [XATO] Faylga kirish taqiqlangan: {fayl_yoli}")
        return []
    except UnicodeDecodeError:
        print(f"  [XATO] Fayl kodlashi noto'g'ri. UTF-8 ekanini tekshiring.")
        return []
    finally:
        print(f"  Fayl o'qish amali tugadi: {fayl_yoli.name}")


def ortacha_baho(qatorlar: list) -> float:
    """Baholar ustuni bo'yicha o'rtachani hisoblaydi, buzuq qatorlarni tashlab ketadi."""
    baholar = []
    buzuq = 0

    for tartib, qator in enumerate(qatorlar, start=2):
        try:
            baholar.append(int(qator["baho"]))
        except (ValueError, KeyError):
            buzuq += 1
            print(f"  [OGOHLANTIRISH] {tartib}-qatordagi baho o'qilmadi")

    if buzuq:
        print(f"  Jami {buzuq} ta qator tashlab yuborildi")

    if not baholar:
        return 0.0
    return sum(baholar) / len(baholar)


qatorlar = csv_oqish("guruh.csv")
if qatorlar:
    print(f"\nO'rtacha baho: {ortacha_baho(qatorlar):.1f}")
else:
    print("\nMa'lumot o'qilmadi.")
Natija
  Fayl o'qish amali tugadi: guruh.csv
  [OGOHLANTIRISH] 4-qatordagi baho o'qilmadi
  Jami 1 ta qator tashlab yuborildi

O'rtacha baho: 84.5
Amaliy topshiriq

kalkulyator_v2.py dasturini yozing:

  1. Foydalanuvchidan ikkita son va amal belgisini so'rang.
  2. try/except bilan ValueError va ZeroDivisionError ni ushlang.
  3. Noma'lum amal kiritilsa, o'zingiz ValueError ko'taring (raise).
  4. finally blokida "Hisob-kitob tugadi" deb yozing.
  5. Barcha xatolarni logging bilan kalkulyator.log fayliga yozing.

Xulosa #

  • try/except xatoni ushlaydi va dasturning to'xtab qolishini oldini oladi.
  • Har doim aniq istisno turini ko'rsating, bo'sh except yozmang.
  • else xato bo'lmaganda, finally esa har doim bajariladi.
  • raise bilan o'zingiz xato ko'tarasiz - bu "fail fast" tamoyili.
  • Exception dan meros olib, o'z istisno klassingizni yaratish mumkin.
  • Real dasturlarda xatolarni logging orqali faylga yozing.

Keyingi bo'limda obyektga yo'naltirilgan dasturlashning asoslarini o'rganamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.