Mundarija (23)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. print debugging cheklovlari
- 2.2. breakpoint()
- 2.3. pdb buyruqlari
- 2.4. Kod qatorida ma'lumot ko'rish
- 2.5. To'xtash nuqtalari (breakpoints)
- 2.6. Post-mortem debugging
- 2.7. traceback — xatoni tahlil
- 2.8. IDE tuzatgichlari
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — traceback bilan xatoni tahlil
- Misol 2 — pdb skriptlangan sessiya
- Misol 3 — Post-mortem va shartli to'xtash
- Misol 4 — Amaliy: xatoni pdb bilan topish
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
- 18-qism yakuni
18.8-dars: Debugging — pdb va IDE
18-QISM — SIFAT VA VOSITALAR · 8-dars · 18-qism yakuni
1. Kirish va motivatsiya
Kod xato beryapti, lekin nima uchun ekani noaniq. Ko'p dasturchi bu yerda print qo'yadi: print("bu yerga yetdi"), print(f"x = {x}"), va natijani ko'zdan kechiradi. Bu ishlaydi, lekin sekin, tartibsiz va cheklangan: har savol uchun yangi print qo'shib, kodni qayta ishga tushirish kerak. Debugger (tuzatgich) — kodni to'xtatib, o'sha nuqtada har qanday o'zgaruvchini tekshirish, qadam-baqadam ijro qilish imkonini beradi. Python'ning o'rnatilgan tuzatgichi — pdb.
Debugger — xatoni tizimli, tez topish vositasi: print bilan "ko'r-ko'rona qidirish" o'rniga, kodni to'xtatib ichini ko'rasiz.
Real vaziyat. Bir dasturchi murakkab funksiyada xato qidirardi — natija noto'g'ri, lekin qayerda buzilayotgani noma'lum. U o'nlab print qo'shdi, kodni qayta-qayta ishga tushirdi, print larni ko'chirdi — bir soat isrof bo'ldi va kod print lar bilan ifloslandi. Keyin hamkasbi breakpoint() qo'yishni o'rgatdi: bitta qatorda kod to'xtadi, u har o'zgaruvchini tekshirdi, qadam-baqadam yurdi va xatoni — noto'g'ri sikl indeksini — besh daqiqada topdi. print lar ham kerak bo'lmadi. Debugger "ko'r qidiruvni" tizimli tekshiruvga aylantirdi.
Bu darsda pdb bilan xatolarni tizimli topishni o'rganamiz va 18-qismni yakunlaymiz.
Bu darsda:
-
printdebugging vs debugger -
breakpoint()vapdbasoslari pdbbuyruqlari (n,s,c,p,l)- To'xtash nuqtalari (breakpoints)
- Post-mortem debugging (xatodan keyin)
traceback— xatoni tahlil qilish- IDE tuzatgichlari
- Amaliy: xatoni pdb bilan topish
- 18-qism yakuni
ℹ
pdbvatraceback— standart kutubxonada.pdbinteraktiv; misollarda u skriptlangan buyruqlar bilan ishga tushiriladi.
2. Nazariya — chuqur tushuntirish
2.1. print debugging cheklovlari
print bilan |
Debugger bilan |
|---|---|
Har savol uchun yangi print |
Istalgan o'zgaruvchini joyida |
| Qayta ishga tushirish | Bir marta to'xtaydi |
| Kodni ifloslantirish | Kodga tegmaydi |
| Faqat oldindan o'ylangan qiymatlar | Har qanday ifoda |
print larni tozalash |
Yo'q |
print debugging tez savollarga yaxshi, lekin murakkab xato uchun sekin va cheklangan. Debugger — tizimli vosita.
2.2. breakpoint()
Python 3.7 dan breakpoint() — koddagi istalgan joyda tuzatgichni ishga tushiradi:
def hisobla(sonlar):
jami = 0
for son in sonlar:
breakpoint() # shu yerda kod to'xtaydi
jami += son
return jamiKod breakpoint() ga yetganda to'xtaydi va (Pdb) so'rovi chiqadi — u yerda buyruqlar kiritasiz.
breakpoint() — import pdb; pdb.set_trace() ning zamonaviy, qisqa shakli. PYTHONBREAKPOINT=0 bilan o'chirish mumkin (ishlab chiqarishda).
2.3. pdb buyruqlari
(Pdb) so'rovida:
| Buyruq | To'liq | Nima qiladi |
|---|---|---|
n |
next | Keyingi qatorga (funksiyaga kirmasdan) |
s |
step | Keyingi qatorga (funksiyaga kirib) |
c |
continue | Keyingi to'xtash nuqtasigacha davom |
p ifoda |
Ifoda qiymatini chiqaradi | |
l |
list | Joriy kod atrofini ko'rsatadi |
w |
where | Chaqiruvlar steki (traceback) |
b qator |
break | To'xtash nuqtasi qo'yadi |
q |
quit | Chiqadi |
r |
return | Funksiya oxirigacha davom |
n vs s: n funksiyani bir qadam sifatida bajaradi, s esa uning ichiga kiradi.
2.4. Kod qatorida ma'lumot ko'rish
(Pdb) da istalgan Python ifodasini yozish mumkin:
(Pdb) p x # x qiymati
(Pdb) p type(x) # x turi
(Pdb) p [i*2 for i in x] # ixtiyoriy ifoda
(Pdb) p locals() # barcha mahalliy o'zgaruvchilar Bu — print debugging'dan asosiy afzallik: print qo'ymasdan, istalgan ifodani joyida tekshirasiz.
2.5. To'xtash nuqtalari (breakpoints)
(Pdb) b 15 # 15-qatorda to'xtash nuqtasi
(Pdb) b funksiya_nomi # funksiyada
(Pdb) b 15, x > 10 # shartli (x > 10 bo'lganda)
(Pdb) c # keyingi to'xtash nuqtasigachaShartli to'xtash nuqtalari — "faqat x manfiy bo'lganda to'xta" kabi holatlarni topish uchun kuchli.
2.6. Post-mortem debugging
Xato yuz bergandan keyin uni tekshirish — xato joyida to'xtab, holatni ko'rish:
import pdb
try:
xato_beruvchi_kod()
except Exception:
pdb.post_mortem() # xato joyida tuzatgich ochiladi
# yoki buyruq qatorida:
# python -m pdb -c continue skript.pyPost-mortem — xato yuz bergan aniq holatni (o'zgaruvchilar, stek) tekshirish imkonini beradi, xatoni qayta yuzaga keltirishga urinmasdan.
2.7. traceback — xatoni tahlil
traceback moduli xato (istisno) ma'lumotini dasturiy tahlil qiladi:
import traceback
try:
kod()
except Exception:
traceback.print_exc() # to'liq traceback
izlar = traceback.format_exc() # satr sifatida traceback — jurnallash 15.16-bob va xatolarni qayd qilishda foydali: xato qayerda, qaysi chaqiruvlar zanjiri orqali yuz berganini ko'rsatadi.
2.8. IDE tuzatgichlari
Zamonaviy IDE lar (VS Code, PyCharm) grafik tuzatgich beradi:
| Imkoniyat | pdb |
IDE |
|---|---|---|
| To'xtash nuqtasi | b/breakpoint() |
Qator yonida bosish |
| O'zgaruvchilar | p |
Panelda avtomatik |
| Qadam-baqadam | n/s |
Tugmalar |
| Chaqiruv steki | w |
Panel |
| Shartli | b ..., shart |
O'ng tugma |
IDE tuzatgichi qulayroq (vizual), pdb esa hamma joyda (server, terminal) ishlaydi. Ikkalasini bilish foydali.
3. Tez ma'lumotnoma
breakpoint() # kod shu yerda to'xtaydi (Python 3.7+)
# (Pdb) buyruqlari:
# n (next), s (step), c (continue)
# p ifoda (print), l (list), w (where)
# b qator (breakpoint), q (quit)
import pdb
pdb.post_mortem() # xatodan keyin
import traceback
traceback.print_exc() # xatoni chiqarishpython -m pdb skript.py # pdb ostida
python -m pdb -c continue skript.py # xatogacha ishga tushirishQoidalar
print debugging o'rniga breakpoint()
n — keyingi qator, s — funksiyaga kirish, c — davom
p ifoda — istalgan ifodani joyida
shartli breakpoint — 'b qator, shart'
post-mortem — xatodan keyin holatni tekshirish
traceback — jurnallash uchun xato tahlili4. Batafsil misollar
pdbinteraktiv bo'lgani uchun misollarda u skriptlangan buyruqlar bilansubprocessorqali ishga tushiriladi; yo'llar normallashtiriladi.
Misol 1 — traceback bilan xatoni tahlil
"""traceback moduli xatoni dasturiy tahlil qiladi: turi, xabari, chaqiruvlar zanjiri; print debugging'dan farqli, xato joyini aniq ko'rsatadi."""
import traceback
def bol(a, b):
return a / b
def hisobla(sonlar):
jami = 0
for son in sonlar:
jami += bol(100, son) # son=0 bo'lsa xato
return jami
def main() -> None:
print("=== 1. Xatoni ushlab tahlil qilish ===")
try:
hisobla([10, 20, 0, 5])
except ZeroDivisionError:
print(" xato turi va joyini traceback ko'rsatadi:")
izlar = traceback.format_exc()
for qator in izlar.splitlines():
# yo'llarni normallashtirish
if "File" in qator and ".py" in qator:
print(f" File \"<skript>\", ...")
elif qator.strip():
print(f" {qator.strip()}")
print("\n=== 2. Istisno ma'lumoti ===")
try:
hisobla([10, 0])
except ZeroDivisionError as xato:
print(f" turi: {type(xato).__name__}")
print(f" xabari: {xato}")
tb = xato.__traceback__
chuqurlik = 0
while tb:
chuqurlik += 1
tb = tb.tb_next
print(f" chaqiruvlar zanjiri chuqurligi: {chuqurlik}")
print("\n=== 3. ⚠️ print debugging vs traceback ===")
print(" print: har o'zgaruvchini qo'lda chiqarish, xato joyini taxmin qilish")
print(" traceback: xato AYNAN qayerda va qaysi chaqiruvlar orqali — avtomatik")
print(" ⭐ traceback jurnallash 15.16-bob uchun ham ishlatiladi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Xatoni ushlab tahlil qilish ===
xato turi va joyini traceback ko'rsatadi:
Traceback (most recent call last):
File "<skript>", ...
hisobla([10, 20, 0, 5])
~~~~~~~^^^^^^^^^^^^^^^^
File "<skript>", ...
jami += bol(100, son) # son=0 bo'lsa xato
~~~^^^^^^^^^^
File "<skript>", ...
return a / b
~~^~~
ZeroDivisionError: division by zero
=== 2. Istisno ma'lumoti ===
turi: ZeroDivisionError
xabari: division by zero
chaqiruvlar zanjiri chuqurligi: 3
=== 3. ⚠️ print debugging vs traceback ===
print: har o'zgaruvchini qo'lda chiqarish, xato joyini taxmin qilish
traceback: xato AYNAN qayerda va qaysi chaqiruvlar orqali — avtomatik
⭐ traceback jurnallash 15.16-bob uchun ham ishlatiladiNima ko'rsatdi: 2.1, 2.7-bo'limlar.
Misol 2 — pdb skriptlangan sessiya
"""pdb ni skriptlangan buyruqlar bilan ishga tushirish: break, continue, print (p); har chaqiruvda o'zgaruvchilarni tekshirish; yo'llar normallashtiriladi."""
import re
import subprocess
import sys
import tempfile
from pathlib import Path
PROG = '''def bol(a, b):
natija = a / b
return natija
def main():
sonlar = [10, 20, 5]
jami = 0
for s in sonlar:
jami += bol(100, s)
return jami
print(main())
'''
# pdb ga beriladigan buyruqlar
BUYRUQLAR = "break bol\ncontinue\np a, b\ncontinue\np a, b\ncontinue\np a, b\nquit\n"
def main() -> None:
with tempfile.TemporaryDirectory() as katalog:
prog = Path(katalog) / "prog.py"
prog.write_text(PROG, encoding="utf-8")
natija = subprocess.run([sys.executable, "-m", "pdb", str(prog)],
input=BUYRUQLAR, capture_output=True, text=True, encoding="utf-8")
print("=== 1. pdb sessiyasi (normallashtirilgan) ===")
for qator in natija.stdout.splitlines():
# Breakpoint e'lon qatorini o'tkazib yuborish (yo'l va tasodifiy tmp nomi bor)
if "Breakpoint" in qator:
continue
# yo'llarni normallashtirish (registrdan qat'i nazar)
qator = re.sub(r"(?i)[a-z]:\\[^ (]*prog\.py\((\d+)\)", r"<prog>:\1 ", qator)
qator = re.sub(r"(?i)[a-z]:\\[^ ]*prog\.py", "<prog>", qator)
if qator.strip():
print(f" {qator}")
print("\n=== 2. Nima bo'ldi ===")
print(" break bol — bol funksiyasida to'xtash nuqtasi")
print(" continue — har chaqiruvda to'xtaydi")
print(" p a, b — argumentlarni ko'radi: (100, 10), (100, 20), (100, 5)")
print(" ⭐ print qo'ymasdan, har chaqiruvda argumentlar tekshirildi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. pdb sessiyasi (normallashtirilgan) ===
> <prog>:1 <module>()
-> def bol(a, b):
(Pdb) > <prog>:2 bol()
-> natija = a / b
(Pdb) (100, 10)
(Pdb) > <prog>:2 bol()
-> natija = a / b
(Pdb) (100, 20)
(Pdb) > <prog>:2 bol()
-> natija = a / b
(Pdb) (100, 5)
(Pdb)
=== 2. Nima bo'ldi ===
break bol — bol funksiyasida to'xtash nuqtasi
continue — har chaqiruvda to'xtaydi
p a, b — argumentlarni ko'radi: (100, 10), (100, 20), (100, 5)
⭐ print qo'ymasdan, har chaqiruvda argumentlar tekshirildiNima ko'rsatdi: 2.2, 2.3, 2.4-bo'limlar.
Misol 3 — Post-mortem va shartli to'xtash
"""post-mortem: xato yuz bergandan keyin holatni tekshirish; -c continue bilan xatogacha ishga tushirish; xato joyidagi o'zgaruvchilarni ko'rish."""
import re
import subprocess
import sys
import tempfile
from pathlib import Path
PROG = '''def hisobla(sonlar):
jami = 0
for i, son in enumerate(sonlar):
jami += 100 / son # son=0 da xato
return jami
hisobla([10, 20, 0, 5])
'''
# xatogacha ishga tushirib, post-mortem holatida o'zgaruvchilarni ko'rish
BUYRUQLAR = "p son\np jami\np i\nquit\n"
def main() -> None:
with tempfile.TemporaryDirectory() as katalog:
prog = Path(katalog) / "prog.py"
prog.write_text(PROG, encoding="utf-8")
# -c continue: skriptni ishga tushiradi, xatoda post-mortem'ga tushadi
natija = subprocess.run([sys.executable, "-m", "pdb", "-c", "continue", str(prog)],
input=BUYRUQLAR, capture_output=True, text=True, encoding="utf-8")
print("=== 1. Post-mortem: xato holatidagi o'zgaruvchilar ===")
for qator in natija.stdout.splitlines():
qator = qator.replace(str(prog), "<prog>")
qator = re.sub(r"[a-zA-Z]:\\[^(]+\((\d+)\)", r"<prog>:\1 ", qator)
if qator.strip() and "Pdb" not in qator.replace("(Pdb)", ""):
# (Pdb) prefiksini soddalashtirish
temiz = qator.replace("(Pdb) ", "").strip()
if temiz:
print(f" {temiz}")
print("\n=== 2. Nima ko'rindi ===")
print(" xato ZeroDivisionError — 100/0")
print(" post-mortem'da: son=0 (xato sababi), i=2 (uchinchi element), jami=15.0")
print(" ⭐ xatoni QAYTA yuzaga keltirmasdan, aniq holatni tekshirdik")
print("\n=== 3. Shartli to'xtash g'oyasi ===")
print(" 'b 4, son == 0' — faqat son nolga teng bo'lganda to'xtaydi")
print(" ⭐ minglab iteratsiyada faqat muammoli holatda to'xtash")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Post-mortem: xato holatidagi o'zgaruvchilar ===
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> <prog>:4 hisobla()
-> jami += 100 / son # son=0 da xato
0
15.0
2
=== 2. Nima ko'rindi ===
xato ZeroDivisionError — 100/0
post-mortem'da: son=0 (xato sababi), i=2 (uchinchi element), jami=15.0
⭐ xatoni QAYTA yuzaga keltirmasdan, aniq holatni tekshirdik
=== 3. Shartli to'xtash g'oyasi ===
'b 4, son == 0' — faqat son nolga teng bo'lganda to'xtaydi
⭐ minglab iteratsiyada faqat muammoli holatda to'xtashNima ko'rsatdi: 2.5, 2.6-bo'limlar.
Misol 4 — Amaliy: xatoni pdb bilan topish
Noto'g'ri natija beruvchi funksiyada xatoni tizimli topamiz. Funksiya o'rtacha qiymatni hisoblashi kerak, lekin noto'g'ri natija beradi. print bilan taxmin qilish o'rniga, pdb bilan kodni to'xtatib, o'zgaruvchilarni tekshirib, xatoni aniqlaymiz. Bu — debugger bilan tizimli xato topishning namunasi.
"""xatoni pdb bilan topish: noto'g'ri natija beruvchi funksiya; skriptlangan pdb sessiyasi bilan o'zgaruvchilarni tekshirish; xatoni aniqlash."""
import re
import subprocess
import sys
import tempfile
from pathlib import Path
# XATO: jami noto'g'ri boshlang'ich qiymatda (0 emas), yoki bo'luvchi noto'g'ri
PROG = '''def ortacha(sonlar):
jami = 0
for son in sonlar:
jami += son
natija = jami / (len(sonlar) - 1) # XATO: -1 ortiqcha
return natija
print(ortacha([10, 20, 30]))
'''
BUYRUQLAR = "break 6\ncontinue\np jami\np len(sonlar)\np jami / len(sonlar)\np jami / (len(sonlar) - 1)\nquit\n"
def main() -> None:
with tempfile.TemporaryDirectory() as katalog:
prog = Path(katalog) / "prog.py"
prog.write_text(PROG, encoding="utf-8")
print("=== 1. Muammo: ortacha([10,20,30]) 20 bo'lishi kerak ===")
natija_xato = subprocess.run([sys.executable, str(prog)], capture_output=True, text=True, encoding="utf-8")
print(f" haqiqiy natija: {natija_xato.stdout.strip()} (kutilgan: 20.0)")
print("\n=== 2. pdb bilan tekshirish ===")
natija = subprocess.run([sys.executable, "-m", "pdb", str(prog)],
input=BUYRUQLAR, capture_output=True, text=True, encoding="utf-8")
for qator in natija.stdout.splitlines():
qator = qator.replace(str(prog), "<prog>")
qator = re.sub(r"[a-zA-Z]:\\[^(]+\((\d+)\)", r"<prog>:\1 ", qator)
temiz = qator.replace("(Pdb) ", "").strip()
if temiz and ("jami" in temiz or "len" in temiz or temiz.replace(".", "").replace(" ", "").isdigit()):
print(f" {temiz}")
print("\n=== 3. Xato topildi ===")
print(" jami = 60, len(sonlar) = 3")
print(" jami / len(sonlar) = 20.0 ← TO'G'RI")
print(" jami / (len(sonlar) - 1) = 30.0 ← kod shuni ishlatgan (XATO)")
print(" ⭐ pdb bo'luvchi noto'g'ri (len-1) ekanini aniq ko'rsatdi")
print(" yechim: 'jami / len(sonlar)' — '-1' olib tashlanadi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Muammo: ortacha([10,20,30]) 20 bo'lishi kerak ===
haqiqiy natija: 30.0 (kutilgan: 20.0)
=== 2. pdb bilan tekshirish ===
60
3
20.0
30.0
=== 3. Xato topildi ===
jami = 60, len(sonlar) = 3
jami / len(sonlar) = 20.0 ← TO'G'RI
jami / (len(sonlar) - 1) = 30.0 ← kod shuni ishlatgan (XATO)
⭐ pdb bo'luvchi noto'g'ri (len-1) ekanini aniq ko'rsatdi
yechim: 'jami / len(sonlar)' — '-1' olib tashlanadiNima ko'rsatdi: 2.2, 2.3, 2.4-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
"print debugging yetarli" |
Murakkab xato uchun sekin, cheklangan |
| "Debugger murakkab" | breakpoint() — bitta qator |
"n funksiyaga kiradi" |
n bir qadam, s funksiyaga kiradi |
| "Faqat oldindan o'ylangan qiymatlar" | p bilan istalgan ifoda |
| "Xatoni qayta yuzaga keltirish kerak" | Post-mortem — xato holatini tekshiradi |
| "IDE tuzatgichi doim yaxshiroq" | pdb — serverda, terminalda ham |
| "Debugger sekinlashtiradi" | Xato topishni tezlashtiradi |
"traceback faqat ekranda" |
Jurnallash uchun ham (format_exc) |
6. Keng tarqalgan xatolar va yechimlari
1. Faqat print debugging
print(f"x = {x}") # ❌ har savol uchun yangi print
breakpoint() # ✅ istalgan ifodani joyida2. print larni tozalashni unutish
print("bu yerga yetdi") # ❌ kodda qoladi
# ✅ breakpoint() — kodni ifloslantirmaydi3. n va s ni chalkashtirish
n # funksiyani bir qadam sifatida # ichiga kirmaydi
s # funksiyaning ICHIGA kiradi # ✅ ichini ko'rish uchun4. Post-mortem o'rniga qayta ishga tushirish
# xatoni qayta yuzaga keltirishga urinish # ❌
python -m pdb -c continue skript.py # ✅ xato holatiga tushadi5. Shartli breakpoint ishlatmaslik
b 15 # ❌ har iteratsiyada to'xtaydi
b 15, x < 0 # ✅ faqat muammoli holatda6. traceback ni jurnalda ishlatmaslik
except Exception as e: log(str(e)) # ❌ joy noma'lum
except Exception: log(traceback.format_exc()) # ✅ to'liq joy7. PYTHONBREAKPOINT ni ishlab chiqarishda
breakpoint() # ⚠️ ishlab chiqarishda qolib ketmasin
# PYTHONBREAKPOINT=0 bilan o'chirish yoki olib tashlash7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 9-qism (o'tilgan): istisnolar —
tracebackbilan tahlil - 15.16-dars (o'tilgan): logging —
traceback.format_excbilan - 17-qism (o'tilgan): testlar — yiqilgan testni pdb bilan tekshirish
- 28.12-dars: Sentry — ishlab chiqarishda xatolarni qayd qilish
- 31-qism: karyera — debugging asosiy ko'nikma
8. Eng yaxshi amaliyotlar
Murakkab xato uchun
printemas,breakpoint()/pdb.n(keyingi qator) vas(funksiyaga kirish) farqini biling.pbilan istalgan ifodani joyida tekshiring.Post-mortem bilan xato holatini qayta yuzaga keltirmasdan tekshiring.
Ko'p iteratsiyada shartli breakpoint (
b qator, shart).traceback.format_excni jurnallashda ishlating.IDE va
pdb— ikkalasini biling (vizual va universal).breakpoint()ni ishlab chiqarishga chiqarmang.
9. Amaliy topshiriq
Vazifa 1: pdb buyruqlarini aniqlang
Har buyruq nima qiladi:
1. n
2. s
3. c
4. p x
5. l
6. w
7. b 15
8. b 15, x > 10
9. q
10. r
11. breakpoint()
12. p locals()Javoblar
- Keyingi qatorga (funksiyaga kirmasdan)
- Keyingi qatorga (funksiyaga kirib)
- Keyingi to'xtash nuqtasigacha davom
xqiymatini chiqaradi- Joriy kod atrofini ko'rsatadi
- Chaqiruvlar steki (where)
- 15-qatorda to'xtash nuqtasi
- Shartli:
x > 10bo'lganda 15-qatorda - Chiqadi (quit)
- Funksiya oxirigacha davom (return)
- Kodni shu yerda to'xtatadi (pdb ochadi)
- Barcha mahalliy o'zgaruvchilar
Vazifa 2: Xatolarni tuzating
1. # xato qidirish:
print("1")
print(f"x={x}")
print("2")
# o'nlab print
2. # funksiya ichini ko'rish:
# (Pdb) n (funksiyaga kirmaydi)
3. # xato yuz berdi, qayta ishga tushirish
# (holatni yo'qotib)
4. # ko'p iteratsiya, har birida to'xtash:
# (Pdb) b 20
5. except Exception as e:
logging.error(str(e)) # joy noma'lumJavoblar
1. breakpoint() # print o'rniga
# (Pdb) p x, y, z # istalgan o'zgaruvchini
2. # (Pdb) s # step — funksiyaga kiradi
3. python -m pdb -c continue skript.py # post-mortem
4. # (Pdb) b 20, muammoli_shart # shartli breakpoint
5. except Exception:
logging.error(traceback.format_exc()) # to'liq joyVazifa 3: Debugging mashqi
Xatoli funksiyani (berilgan) pdb bilan tuzating:
breakpoint()yokipdbbilan to'xtating- O'zgaruvchilarni tekshirib xatoni toping
- Qadam-baqadam (
n/s) ijroni kuzating - Xatoni tuzatib, test bilan tasdiqlang (17-qism)
Vazifa 4: Post-mortem
Istisno beruvchi skript uchun:
python -m pdb -c continuebilan ishga tushiring- Xato holatidagi o'zgaruvchilarni tekshiring
- Chaqiruvlar stekini (
w) ko'ring - Xato sababini aniqlang
Vazifa 5: Shartli breakpoint
Ko'p iteratsiyali siklda xato bor:
- Oddiy breakpoint har iteratsiyada to'xtashini ko'ring
- Shartli breakpoint bilan faqat muammoli holatda
- Muammoli iteratsiya holatini tekshiring
- Xatoni toping
Vazifa 6: traceback bilan jurnallash
- Istisnoni ushlab,
traceback.format_excbilan jurnalga yozing (15.16) - Xato turi, xabari va to'liq stekni saqlang
- Foydalanuvchiga qisqa xabar, jurnalga to'liq
- JSON jurnal formatida (16.2)
Vazifa 7: O'ylash
"Debugging" atamasi 1940-yillarda haqiqiy hasharot (bug — moth) kompyuterga tushib qolgan voqeadan kelib chiqqan degan mashhur rivoyat bor. Bugungi kunda debugging dasturchining vaqtining katta qismini (ba'zi tadqiqotlarga ko'ra 50% dan ko'p) egallaydi. Nima uchun debugging shunchalik ko'p vaqt oladi, va yaxshi debugging ko'nikmasi (va profilaktika — test, tur, lint) uni qanday kamaytiradi?
Javob
Qisqa javob: Debugging ko'p vaqt oladi, chunki xato belgisi (noto'g'ri natija) va sababi (koddagi aniq joy) ko'pincha bir-biridan uzoq: belgini ko'rasiz, lekin sababni topish uchun kodning ichini kuzatish kerak. Yaxshi debugging ko'nikmasi (tizimli yondashuv, debugger) bu masofani tez bosib o'tadi. Lekin eng katta tejamkorlik — profilaktika: test (17-qism) xatoni erta ushlaydi, tur tekshiruvi (13-qism) butun sinf xatolarni oldini oladi, lint 18.4-bob xavfli naqshlarni topadi. Eng yaxshi debugging — umuman kerak bo'lmagani.
1. Nega debugging ko'p vaqt oladi
| Sabab | Tafsilot |
|---|---|
| Belgi ≠ sabab | Noto'g'ri natija koddan uzoq |
| Holat murakkab | Ko'p o'zgaruvchi, ko'p yo'l |
| Qayta yuzaga keltirish | Xatoni takrorlash qiyin |
| Taxmin | print bilan ko'r qidiruv |
| Kontekst yo'qolishi | Xato joyidagi holat noma'lum |
2. Yaxshi debugging ko'nikmasi
| Ko'nikma | Tejamkorlik |
|---|---|
| Tizimli yondashuv | Taxmin emas, kuzatish |
| Debugger (pdb/IDE) | Holatni joyida ko'rish |
| Traceback o'qish | Xato joyini tez topish |
| Ikkiga bo'lish (bisection) | Muammoni toraytirish |
| Gipoteza-tekshiruv | Ilmiy yondashuv |
3. Profilaktika — eng katta tejamkorlik
| Vosita | Nimani oldini oladi |
|---|---|
| Test (17-qism) | Xatoni erta ushlaydi |
| Tur (13-qism) | Butun sinf xatolar |
| Lint (18.4) | Xavfli naqshlar |
| Kod ko'rigi | Ikkinchi ko'z |
| Toza kod | Kam xato |
4. "Chapga siljish" (18.6)
Xatoni qancha erta ushlasa, shuncha arzon: yozayotib (tur, lint) → test → debugging → ishlab chiqarish. Debugging — oxirgi himoya, profilaktika — birinchi.
5. Muhandislik saboqlari
- Debugging — tizimli, ilmiy jarayon (taxmin emas)
- Debugger — asosiy vosita (print emas)
- Profilaktika debugging'dan arzonroq
- Eng yaxshi xato — yuz bermagan xato
6. Xulosa
- Debugging ko'p vaqt oladi: belgi va sabab uzoq
- Yaxshi ko'nikma (debugger, tizimlilik) tezlashtiradi
- Profilaktika (test, tur, lint) eng katta tejamkorlik
- Debugging — oxirgi himoya, sifat — butun jarayon
Nimani mustahkamlaydi: 2.1–2.8-bo'limlar.
Xulosa
Bu darsda pdb bilan xatolarni tizimli topishni o'rgandik.
Eng muhim uch fikr:
Debugger —
printdebugging'dan kuchli.printdebugging har savol uchun yangiprintqo'shib, kodni qayta ishga tushirishni talab qiladi va kodni ifloslantiradi.breakpoint()(Python 3.7+) koddagi istalgan joyda tuzatgichni ishga tushiradi: kod to'xtaydi va(Pdb)so'rovidap ifodabilan istalgan o'zgaruvchini yoki ifodani joyida tekshirasiz —printqo'ymasdan.pdbbuyruqlari va post-mortem. Asosiy buyruqlar:n(keyingi qator, funksiyaga kirmasdan),s(funksiyaga kirib),c(davom),p(chiqarish),w(chaqiruvlar steki),b(to'xtash nuqtasi — shartli ham:b 15, x > 10). Post-mortem debugging (python -m pdb -c continue) xato yuz bergandan keyin aniq holatni (o'zgaruvchilar, stek) qayta yuzaga keltirmasdan tekshiradi.tracebackmoduli xatoni dasturiy tahlil qiladi — jurnallash 15.16-bob uchunformat_exc.Debugging — tizimli jarayon, profilaktika — arzonroq. Xato belgisi va sababi ko'pincha uzoq — debugger bu masofani tez bosib o'tadi (taxmin emas, kuzatish). IDE tuzatgichi vizual va qulayroq,
pdbesa hamma joyda (server, terminal) ishlaydi. Lekin eng katta tejamkorlik — profilaktika: test (17-qism), tur (13-qism), lint 18.4-bob xatolarni erta ushlaydi. Eng yaxshi debugging — umuman kerak bo'lmagani.
Bu bilan 18-qism — Sifat va vositalar yakunlandi. Keyingi 19-qismda o'z kodingizni paketlash va ulashishni o'rganamiz: pyproject.toml bilan paket yaratish, PyPI ga nashr qilish va CLI vositalar qurish.
18-qism yakuni
Sifat va vositalar qismida professional dasturchining kundalik asboblar to'plamini o'rgandik — muhitdan tuzatgichgacha.
| Dars | Vosita | Asosiy g'oya |
|---|---|---|
| 18.1 | venv |
Loyihalarni izolyatsiya qilish |
| 18.2 | pip |
Bog'liqliklar va versiya belgilash |
| 18.3 | poetry/uv |
Birlashtirilgan, tez ish oqimi |
| 18.4 | ruff |
Lint — muammolarni statik topish |
| 18.5 | black |
Format — izchil ko'rinish |
| 18.6 | pre-commit |
Sifatni git oqimiga singdirish |
| 18.7 | Profiling | Taxmin qilma, o'lcha |
| 18.8 | Debugging | Tizimli xato topish |
Umumiy tamoyillar:
- Izolyatsiya va takrorlanuvchanlik: har loyiha alohida muhit, qulflangan bog'liqliklar.
- Avtomatlashtirish: lint, format, tekshiruvlar — qo'lda emas,
pre-commitva CI. - O'lchov, taxmin emas: profiling bilan optimizatsiya, debugger bilan xato topish.
- Chapga siljish: muammolarni imkon qadar erta (muharrir, commit) ushlash.
Keyingi bosqich — paketlash (19): o'z kodingizni kutubxona yoki vosita sifatida qadoqlab, boshqalar bilan ulashish.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!