Xatolar va ularni tuzatish
Har bir dasturchi — hatto eng tajribalisi ham — har kuni xato qiladi. Professionalni yangi boshlovchidan ajratib turadigan narsa xatosizlik emas, balki xatoni tez topib, tuzata olish. Bu darsda aynan shu mahoratni o'rganamiz.
Bu darsda
- Xatolarning uch turi
- Xato xabarini (traceback) o'qish
- Eng ko'p uchraydigan xatolar va ularning sabablari
try/except— xatolarni ushlash- Xatolarni topishning amaliy usullari
Inglizcha «bug» (qo'ng'iz, hasharot) so'zi dasturdagi xatoni bildiradi, xatoni tuzatish esa debugging deyiladi. Mashhur rivoyatga ko'ra, 1947-yilda Garvard universitetidagi Mark II kompyuteri ishdan chiqqanda, uning ichidan haqiqiy kapalak topilgan. Muhandislar uni jurnalga yopishtirib, «Haqiqiy bug topilgan birinchi holat» deb yozib qo'yishgan. O'sha sahifa hozir ham muzeyda saqlanadi.
Xatolarning uch turi
1. Sintaksis xatolari
Kod Python qoidalariga mos emas — qavs yopilmagan, ikki nuqta tushib qolgan, qo'shtirnoq yetishmaydi. Python bunday kodni umuman ishga tushirmaydi, darhol SyntaxError beradi. Bu eng oson tuzatiladigan xatolar: Python joyini aniq ko'rsatadi.
print("Dastur boshlandi")
if 5 > 3
print("Besh uchdan katta")
E'tibor bering: birinchi qator ham bajarilmadi. Sintaksis xatosi bo'lsa, Python kodni boshlamasdanoq to'xtaydi.
2. Bajarilish paytidagi xatolar
Kod to'g'ri yozilgan, lekin bajarilayotganda imkonsiz ish uchradi: nolga bo'lish, yo'q faylni ochish, matnni songa aylantirish. Bunday xatolar istisno (inglizcha exception) deyiladi. Dastur xatoga yetguncha ishlaydi, keyin to'xtaydi:
print("Hisob boshlandi")
pul = 100000
odamlar = 0
print("Har biriga:", pul / odamlar)
print("Bu qator bajarilmaydi")
3. Mantiqiy xatolar
Eng ayyor xatolar. Dastur xatosiz ishlaydi, lekin noto'g'ri natija beradi. Python hech narsa demaydi — chunki u siz nima qilmoqchi ekaningizni bilmaydi:
a = 4
b = 5
c = 3
ortacha = a + b + c / 3
print("O'rtacha:", ortacha)
Natija 10.0 chiqdi, lekin 4, 5, 3 ning o'rtachasi 4 bo'lishi kerak! Sabab — amallar tartibi: faqat c 3 ga bo'lindi. To'g'risi: (a + b + c) / 3. Mantiqiy xatolarni topishning yagona yo'li — natijani diqqat bilan tekshirish.
Xato xabarini o'qish
Python xato haqida xabar berganda, u traceback («izni kuzatish») deb ataladigan hisobot chiqaradi. Uni qo'rqmasdan o'qishni o'rganing — u xatoni topishdagi eng yaxshi yordamchingiz:
def ortacha(sonlar):
return sum(sonlar) / len(sonlar)
baholar = []
print(ortacha(baholar))
Traceback (most recent call last):
File "<kod>", line 5, in <module>
print(ortacha(baholar))
~~~~~~~^^^^^^^^^
File "<kod>", line 2, in ortacha
return sum(sonlar) / len(sonlar)
~~~~~~~~~~~~^~~~~~~~~~~~~
ZeroDivisionError: division by zero
Traceback'ni pastdan yuqoriga o'qing:
- Oxirgi qator — eng muhimi: xato turi (
ZeroDivisionError) va sababi (division by zero — «nolga bo'lish»). - Undan yuqorisi — xato aynan qayerda bo'lgani: 2-qator,
ortachafunksiyasi ichida.^belgilari muammoli qismni ko'rsatadi. - Eng yuqorisi — bu funksiya qayerdan chaqirilgani: 5-qator.
Xulosa: bo'sh ro'yxat uzunligi 0, unga bo'lish mumkin emas. Yechim — ro'yxat bo'sh emasligini oldindan tekshirish.
Eng ko'p uchraydigan xatolar
| Xato | Ma'nosi | Odatiy sababi |
|---|---|---|
SyntaxError | Yozish qoidasi buzilgan | Qavs, qo'shtirnoq yoki : yetishmaydi |
IndentationError | Chekinish noto'g'ri | Blokda bo'sh joylar soni har xil |
NameError | Bunday nom yo'q | O'zgaruvchi nomi xato yozilgan yoki unga hali qiymat berilmagan |
TypeError | Tur mos emas | "5" + 3 — matn va sonni qo'shish |
ValueError | Qiymat yaroqsiz | int("salom") |
ZeroDivisionError | Nolga bo'lish | Bo'luvchi 0 ga teng |
IndexError | Bunday indeks yo'q | 3 elementli ro'yxatda [3] so'raldi |
KeyError | Bunday kalit yo'q | Lug'atda kalit mavjud emas |
AttributeError | Bunday metod yo'q | "salom".push() — satrda push metodi yo'q |
Bu saytdagi muharrir har bir xato ostida uning o'zbekcha tushuntirishini beradi va xato qatorini qizil rang bilan belgilaydi. Lekin asl xabarni ham o'qishga odatlaning — kompyuteringizdagi Python faqat inglizcha xabar beradi.
try / except — xatolarni ushlash
Ba'zi xatolarni oldindan bilish mumkin. Masalan, foydalanuvchi son o'rniga harf yozishi mumkin. Bunday holatda dastur «yiqilib» qolmasligi uchun xatoni ushlab, o'zimiz hal qilamiz:
try:
yosh = int(input("Yoshingiz: "))
print("Kelasi yili", yosh + 1, "yoshda bo'lasiz")
except ValueError:
print("Iltimos, yoshingizni raqam bilan yozing.")
Yoshingiz: o'n yetti Iltimos, yoshingizni raqam bilan yozing.
Qanday ishlaydi:
- Python
try(«urinib ko'r») blokini bajaradi. - Agar u yerda xato bo'lmasa —
exceptbloki tashlab o'tiladi. - Agar
ValueErroryuz bersa —tryblokining qolgan qismi bajarilmaydi, darholexcept(«istisno holda») blokiga o'tiladi. Dastur to'xtamaydi!
To'g'ri javob berilguncha so'rash
while True, try va break birgalikda foydalanuvchi to'g'ri son kiritguncha so'rab turadi. Bu juda ko'p ishlatiladigan andoza:
while True:
try:
son = int(input("Butun son kiriting: "))
break # xato bo'lmasa, sikldan chiqamiz
except ValueError:
print("Bu butun son emas. Qaytadan urinib ko'ring.")
print("Rahmat! Siz", son, "kiritdingiz.")
Butun son kiriting: abc Bu butun son emas. Qaytadan urinib ko'ring. Butun son kiriting: 12.5 Bu butun son emas. Qaytadan urinib ko'ring. Butun son kiriting: 7 Rahmat! Siz 7 kiritdingiz.
Bir nechta xato turi
Turli xatolar uchun turli except bloklarini yozish mumkin:
try:
a = int(input("Bo'linuvchi: "))
b = int(input("Bo'luvchi: "))
print("Natija:", a / b)
except ValueError:
print("Faqat butun son kiriting.")
except ZeroDivisionError:
print("Nolga bo'lib bo'lmaydi.")
Shunchaki except: deb, xato turini ko'rsatmasdan yozish mumkin, lekin bu yomon odat. Bunday blok barcha xatolarni, jumladan siz kutmagan va bilishingiz kerak bo'lgan xatolarni ham «yutib yuboradi». Har doim aniq xato turini yozing.
Xato xabarini olish
as yordamida xato haqidagi ma'lumotni o'zgaruvchiga olish mumkin:
mahsulotlar = {"non": 4000, "sut": 12000}
try:
print(mahsulotlar["qatiq"])
except KeyError as xato:
print("Topilmadi:", xato)
Xatolarni topish usullari
Xato xabari bo'lmasa (mantiqiy xato) yoki u tushunarsiz bo'lsa, quyidagi usullar yordam beradi:
- Xabarni oxirigacha o'qing. Ko'pincha javob o'sha yerda yozilgan bo'ladi. Python hatto Did you mean...? («...demoqchimidingiz?») deb maslahat ham beradi.
print()bilan kuzating. Shubhali joylarga o'zgaruvchilar qiymatini chiqaradigan qatorlar qo'ying:print("DEBUG: x =", x, type(x)). Qiymat kutganingizdek emasligini ko'rgan joyingiz — xato atrofi.- Kichik qismlarga bo'ling. Dasturning yarmini izohga aylantirib, xato qaysi qismda ekanini aniqlang.
- Qo'lda kuzating. 10-darsdagi kabi jadval chizib, har bir qadamda o'zgaruvchilar qiymatini qog'ozda yozing.
- «O'yinchoq o'rdak» usuli. Kodingizni qatorma-qator kimgadir — hatto stol ustidagi o'yinchoqqa — ovoz chiqarib tushuntiring. Ko'pincha tushuntirish jarayonida xato o'zi ko'zga tashlanadi. Bu usul dasturchilar orasida jiddiy ravishda rubber duck debugging deb ataladi.
- Internetdan qidiring. Xato xabarining oxirgi qatorini nusxalab, qidiruv tizimiga yozing. Siz bu xatoga duch kelgan birinchi odam emassiz — javob deyarli doim bor.
- Dam oling. Bir soat xato qidirib topa olmasangiz, 10 daqiqa tanaffus qiling. Toza ko'z bilan qaraganda xato ko'pincha darhol ko'rinadi.
Mashqlar
1-mashq Uchta xato
Dasturda uchta xato bor: sintaksis, nom va mantiqiy. Hammasini tuzating — dastur Jami: 15000 va O'rtacha: 5000.0 chiqarishi kerak.
narxlar = [4000, 5000, 6000]
jami = 0
for narx in narxlar
jami += narx
print("Jami:", Jami)
print("O'rtacha:", jami / len(narxlar) + 1)
Ishora
Python xatolarni birma-bir ko'rsatadi. Sintaksis xatosini tuzatgach, keyingisi chiqadi. Mantiqiy xatoni esa natijani kutilgani bilan solishtirib topasiz.
Yechimni ko'rish
narxlar = [4000, 5000, 6000]
jami = 0
for narx in narxlar:
jami += narx
print("Jami:", jami)
print("O'rtacha:", jami / len(narxlar))
3-qatorda : yetishmagan (sintaksis), 5-qatorda Jami katta harf bilan yozilgan (nom), 6-qatorda esa ortiqcha + 1 bor edi (mantiqiy).
2-mashq Xavfsiz bo'lish
bolish(a, b) funksiyasini yozing: u a / b ni qaytarsin, lekin b nol bo'lsa, xato o'rniga Nolga bo'lib bo'lmaydi matnini qaytarsin. try / except dan foydalaning.
def bolish(a, b):
return a / b
print(bolish(10, 2))
print(bolish(1, 0))
Yechimni ko'rish
def bolish(a, b):
try:
return a / b
except ZeroDivisionError:
return "Nolga bo'lib bo'lmaydi"
print(bolish(10, 2))
print(bolish(1, 0))
3-mashq Musbat son
Foydalanuvchidan musbat butun son so'rang. U harf yozsa — Bu son emas, manfiy son yoki nol yozsa — Son musbat bo'lishi kerak deb, qaytadan so'rang. To'g'ri son kiritilgach, uning kvadratini chiqaring.
# Kodingizni shu yerga yozing
Yechimni ko'rish
while True:
try:
son = int(input("Musbat son: "))
except ValueError:
print("Bu son emas")
continue
if son <= 0:
print("Son musbat bo'lishi kerak")
continue
break
print("Kvadrati:", son ** 2)
Musbat son: besh Bu son emas Musbat son: -5 Son musbat bo'lishi kerak Musbat son: 5 Kvadrati: 25
O'zingizni sinang
Qaysi xato turida Python hech qanday xabar bermaydi?
- Sintaksis xatosi
- Bajarilish paytidagi xato
- Mantiqiy xato
- Python har doim xabar beradi
To'g'ri. Mantiqiy xatoda dastur ishlaydi, lekin noto'g'ri natija beradi.
Traceback'ning qaysi qismini birinchi navbatda o'qish kerak?
- Oxirgi qatorni — xato turi va sababini
- Birinchi qatorni — «Traceback»
- O'rtadagi
^belgilarini - Hech birini — darhol kodni o'zgartirish kerak
To'g'ri. Pastdan yuqoriga o'qing: avval nima bo'ldi, keyin qayerda.
int("12a") qaysi xatoni beradi?
TypeErrorNameErrorSyntaxErrorValueError
To'g'ri. Tur to'g'ri (satr), lekin uning qiymatini butun songa aylantirib bo'lmaydi.
try blokida xato yuz bermasa, nima bo'ladi?
exceptbloki ham bajariladiexceptbloki tashlab o'tiladi- Dastur to'xtaydi
trybloki ikki marta bajariladi
To'g'ri. except faqat xato yuz berganda ishlaydi.
Xulosa
- Xatolar uch xil: sintaksis (kod ishga tushmaydi), bajarilish paytidagi (dastur to'xtaydi) va mantiqiy (natija noto'g'ri).
- Traceback'ni pastdan yuqoriga o'qing: oxirgi qatorda — xato turi va sababi, yuqorida — qayerda bo'lgani.
try/except XatoTuri:— kutilgan xatolarni ushlab, dasturni to'xtatmasdan hal qiladi.- Bo'sh
except:dan qoching — aniq xato turini yozing. - Xatoni topish uchun: xabarni o'qing,
print()bilan kuzating, qismlarga bo'ling, tushuntirib ko'ring, qidiring.