14-bo‘lim
Xatoliklar va istisnolar
Xato turlari, try/except/else/finally konstruksiyasi, raise bilan xato ko'tarish va o'z istisno klassingizni yaratish.
Ushbu bo‘lim mundarijasi
- Xatolarning uch turi
- Eng ko'p uchraydigan istisnolar
- try ... except
- Bir nechta istisnoni birga ushlash
- else va finally
- Xato haqida ma'lumot olish
- raise - xatoni o'zingiz ko'tarish
- O'z istisno klassingiz
- Xavfsiz kiritish funksiyasi
- Xatolarni jurnalga yozish
- Amaliy misol: ishonchli fayl o'quvchi
- Xulosa
Xatosiz dastur bo'lmaydi. Yaxshi dastur xatolardan qochmaydi - ularni to'g'ri boshqaradi.
Xatolarning uch turi #
Eng ko'p uchraydigan istisnolar #
| Istisno | Qachon yuz beradi | Misol |
|---|---|---|
ValueError | Qiymat noto'g'ri turda | int("salom") |
TypeError | Turlar mos kelmadi | "5" + 5 |
ZeroDivisionError | Nolga bo'lish | 10 / 0 |
IndexError | Indeks chegaradan tashqarida | [1,2][5] |
KeyError | Lug'atda kalit yo'q | {"a":1}["b"] |
FileNotFoundError | Fayl topilmadi | open("yoq.txt") |
AttributeError | Obyektda bunday metod yo'q | "matn".append() |
NameError | O'zgaruvchi e'lon qilinmagan | print(mavjudmas) |
ImportError | Modul topilmadi | import mavjudmas |
PermissionError | Faylga ruxsat yo'q | Tizim fayliga yozish |
try ... except #
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!")
Son kiriting: salom
Xato: faqat son kiriting!
Son kiriting: 0
Xato: nolga bo'lib bo'lmaydi!
Son kiriting: 4
Natija: 25.0
Bir nechta istisnoni birga ushlash #
try:
qiymat = int(input("Son: "))
print(10 / qiymat)
except (ValueError, ZeroDivisionError) as xato:
print(f"Kiritishda muammo: {xato}")
Son: 0
Kiritishda muammo: division by zero
except yozmangtry:
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:
try:
xavfli_amal()
except ValueError as xato:
print(f"Qiymat xatosi: {xato}")
else va finally #
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.")
Fayl topilmadi!
Amal tugadi.
| Blok | Qachon bajariladi |
|---|---|
try | Har doim (birinchi) |
except | Faqat mos xato yuz berganda |
else | Faqat hech qanday xato bo'lmaganda |
finally | Har 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 #
try:
sonlar = [1, 2, 3]
print(sonlar[10])
except IndexError as xato:
print(f"Xato turi: {type(xato).__name__}")
print(f"Xabar: {xato}")
Xato turi: IndexError
Xabar: list index out of range
raise - xatoni o'zingiz ko'tarish #
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}")
Yosh qabul qilindi: 25
Tekshiruv muvaffaqiyatsiz: Yosh manfiy bo'lishi mumkin emas
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:
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")
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:
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.")
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:
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))
5.0
None
xatolar.log fayli mazmuni:
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
| Daraja | Qachon ishlatiladi |
|---|---|
DEBUG | Nosozlikni tuzatish uchun tafsilotlar |
INFO | Oddiy ish jarayoni haqida xabar |
WARNING | Muammo bo'lishi mumkin, lekin ishlayapti |
ERROR | Amal bajarilmadi |
CRITICAL | Dastur to'xtash arafasida |
Amaliy misol: ishonchli fayl o'quvchi #
# ============================================
# 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.")
Fayl o'qish amali tugadi: guruh.csv
[OGOHLANTIRISH] 4-qatordagi baho o'qilmadi
Jami 1 ta qator tashlab yuborildi
O'rtacha baho: 84.5
kalkulyator_v2.py dasturini yozing:
- Foydalanuvchidan ikkita son va amal belgisini so'rang.
try/exceptbilanValueErrorvaZeroDivisionErrorni ushlang.- Noma'lum amal kiritilsa, o'zingiz
ValueErrorko'taring (raise). finallyblokida "Hisob-kitob tugadi" deb yozing.- Barcha xatolarni
loggingbilankalkulyator.logfayliga yozing.
Xulosa #
try/exceptxatoni ushlaydi va dasturning to'xtab qolishini oldini oladi.- Har doim aniq istisno turini ko'rsating, bo'sh
exceptyozmang. elsexato bo'lmaganda,finallyesa har doim bajariladi.raisebilan o'zingiz xato ko'tarasiz - bu "fail fast" tamoyili.Exceptiondan meros olib, o'z istisno klassingizni yaratish mumkin.- Real dasturlarda xatolarni
loggingorqali faylga yozing.
Keyingi bo'limda obyektga yo'naltirilgan dasturlashning asoslarini o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.