IlmHamroh
Python kursi/Sifat va vositalar8/8-dars19 daqiqa
Mundarija (23)

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:

  • print debugging vs debugger
  • breakpoint() va pdb asoslari
  • pdb buyruqlari (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

ℹ pdb va traceback — standart kutubxonada. pdb interaktiv; 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:

python
def hisobla(sonlar):
    jami = 0
    for son in sonlar:
        breakpoint()          # shu yerda kod to'xtaydi
        jami += son
    return jami

Kod 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 print 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 nuqtasigacha

Shartli 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:

python
import pdb

try:
    xato_beruvchi_kod()
except Exception:
    pdb.post_mortem()        # xato joyida tuzatgich ochiladi

# yoki buyruq qatorida:
# python -m pdb -c continue skript.py

Post-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:

python
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

python
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 chiqarish
bash
python -m pdb skript.py                 # pdb ostida
python -m pdb -c continue skript.py     # xatogacha ishga tushirish

Qoidalar

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 tahlili

4. Batafsil misollar

pdb interaktiv bo'lgani uchun misollarda u skriptlangan buyruqlar bilan subprocess orqali ishga tushiriladi; yo'llar normallashtiriladi.

Misol 1 — traceback bilan xatoni tahlil

python
"""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:

text
=== 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 ishlatiladi

Nima ko'rsatdi: 2.1, 2.7-bo'limlar.

Misol 2 — pdb skriptlangan sessiya

python
"""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:

text
=== 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 tekshirildi

Nima ko'rsatdi: 2.2, 2.3, 2.4-bo'limlar.

Misol 3 — Post-mortem va shartli to'xtash

python
"""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:

text
=== 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'xtash

Nima 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.

python
"""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:

text
=== 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 tashlanadi

Nima 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

python
print(f"x = {x}")                          # ❌ har savol uchun yangi print
breakpoint()                               # ✅ istalgan ifodani joyida

2. print larni tozalashni unutish

python
print("bu yerga yetdi")                    # ❌ kodda qoladi
# ✅ breakpoint() — kodni ifloslantirmaydi

3. n va s ni chalkashtirish

n   # funksiyani bir qadam sifatida        # ichiga kirmaydi
s   # funksiyaning ICHIGA kiradi           # ✅ ichini ko'rish uchun

4. Post-mortem o'rniga qayta ishga tushirish

python
# xatoni qayta yuzaga keltirishga urinish   # ❌
python -m pdb -c continue skript.py         # ✅ xato holatiga tushadi

5. Shartli breakpoint ishlatmaslik

b 15                                       # ❌ har iteratsiyada to'xtaydi
b 15, x < 0                                # ✅ faqat muammoli holatda

6. traceback ni jurnalda ishlatmaslik

python
except Exception as e: log(str(e))         # ❌ joy noma'lum
except Exception: log(traceback.format_exc())   # ✅ to'liq joy

7. PYTHONBREAKPOINT ni ishlab chiqarishda

python
breakpoint()                               # ⚠️ ishlab chiqarishda qolib ketmasin
# PYTHONBREAKPOINT=0 bilan o'chirish yoki olib tashlash

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 9-qism (o'tilgan): istisnolar — traceback bilan tahlil
  • 15.16-dars (o'tilgan): logging — traceback.format_exc bilan
  • 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

  1. Murakkab xato uchun print emas, breakpoint()/pdb.

  2. n (keyingi qator) va s (funksiyaga kirish) farqini biling.

  3. p bilan istalgan ifodani joyida tekshiring.

  4. Post-mortem bilan xato holatini qayta yuzaga keltirmasdan tekshiring.

  5. Ko'p iteratsiyada shartli breakpoint (b qator, shart).

  6. traceback.format_exc ni jurnallashda ishlating.

  7. IDE va pdb — ikkalasini biling (vizual va universal).

  8. 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
  1. Keyingi qatorga (funksiyaga kirmasdan)
  2. Keyingi qatorga (funksiyaga kirib)
  3. Keyingi to'xtash nuqtasigacha davom
  4. x qiymatini chiqaradi
  5. Joriy kod atrofini ko'rsatadi
  6. Chaqiruvlar steki (where)
  7. 15-qatorda to'xtash nuqtasi
  8. Shartli: x > 10 bo'lganda 15-qatorda
  9. Chiqadi (quit)
  10. Funksiya oxirigacha davom (return)
  11. Kodni shu yerda to'xtatadi (pdb ochadi)
  12. Barcha mahalliy o'zgaruvchilar

Vazifa 2: Xatolarni tuzating

python
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'lum
Javoblar
python
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 joy

Vazifa 3: Debugging mashqi

Xatoli funksiyani (berilgan) pdb bilan tuzating:

  1. breakpoint() yoki pdb bilan to'xtating
  2. O'zgaruvchilarni tekshirib xatoni toping
  3. Qadam-baqadam (n/s) ijroni kuzating
  4. Xatoni tuzatib, test bilan tasdiqlang (17-qism)

Vazifa 4: Post-mortem

Istisno beruvchi skript uchun:

  1. python -m pdb -c continue bilan ishga tushiring
  2. Xato holatidagi o'zgaruvchilarni tekshiring
  3. Chaqiruvlar stekini (w) ko'ring
  4. Xato sababini aniqlang

Vazifa 5: Shartli breakpoint

Ko'p iteratsiyali siklda xato bor:

  1. Oddiy breakpoint har iteratsiyada to'xtashini ko'ring
  2. Shartli breakpoint bilan faqat muammoli holatda
  3. Muammoli iteratsiya holatini tekshiring
  4. Xatoni toping

Vazifa 6: traceback bilan jurnallash

  1. Istisnoni ushlab, traceback.format_exc bilan jurnalga yozing (15.16)
  2. Xato turi, xabari va to'liq stekni saqlang
  3. Foydalanuvchiga qisqa xabar, jurnalga to'liq
  4. 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

  1. Debugging — tizimli, ilmiy jarayon (taxmin emas)
  2. Debugger — asosiy vosita (print emas)
  3. Profilaktika debugging'dan arzonroq
  4. Eng yaxshi xato — yuz bermagan xato

6. Xulosa

  1. Debugging ko'p vaqt oladi: belgi va sabab uzoq
  2. Yaxshi ko'nikma (debugger, tizimlilik) tezlashtiradi
  3. Profilaktika (test, tur, lint) eng katta tejamkorlik
  4. 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:

  1. Debugger — print debugging'dan kuchli. print debugging har savol uchun yangi print qo'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'rovida p ifoda bilan istalgan o'zgaruvchini yoki ifodani joyida tekshirasiz — print qo'ymasdan.

  2. pdb buyruqlari 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. traceback moduli xatoni dasturiy tahlil qiladi — jurnallash 15.16-bob uchun format_exc.

  3. 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, pdb esa 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:

  1. Izolyatsiya va takrorlanuvchanlik: har loyiha alohida muhit, qulflangan bog'liqliklar.
  2. Avtomatlashtirish: lint, format, tekshiruvlar — qo'lda emas, pre-commit va CI.
  3. O'lchov, taxmin emas: profiling bilan optimizatsiya, debugger bilan xato topish.
  4. Chapga siljish: muammolarni imkon qadar erta (muharrir, commit) ushlash.

Keyingi bosqich — paketlash (19): o'z kodingizni kutubxona yoki vosita sifatida qadoqlab, boshqalar bilan ulashish.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
18.8-dars: Debugging — pdb va IDE — IlmHamroh