לדלג לתוכן

דיבוג בפייתון עם pdb

בואו נדבר בכנות. כולנו התחלנו לדבג ככה - מפזרים print בכל מקום שבו חושדים שמשהו משתבש, מריצים שוב, מסתכלים בפלט, מוחקים את ה-print, מוסיפים אותו במקום אחר, ומריצים שוב. זה עובד, בערך, אבל זה איטי ומעייף, ובבאגים מסובכים יותר זה פשוט לא מספיק. יש דרך טובה יותר, וקוראים לה pdb.

למה print לא תמיד מספיק

הבעיה עם דיבוג באמצעות print היא שאתם צריכים לנחש מראש איפה הבעיה, להוסיף הדפסה, להריץ הכל מחדש, ולחזור על זה שוב ושוב עד שתתקלו במקום הנכון. זה גם מבלגן את הקוד עם שורות הדפסה שצריך לזכור למחוק אחר כך, ולא נותן לכם שום דרך "לעצור" את התוכנית באמצע ולבדוק לעומק מה קורה עם המשתנים בדיוק ברגע הזה. דיבאגר פותר את כל זה - הוא עוצר את התוכנית בדיוק במקום שביקשתם, ונותן לכם לחקור את המצב בחופשיות.

איך נכנסים ל-pdb

בפייתון מודרנית הדרך הכי פשוטה היא להוסיף שורה אחת בקוד, במקום שבו אתם רוצים שהתוכנית תעצור:

def divide(a, b):
    breakpoint()
    return a / b

כשהריצה מגיעה לשורה הזאת, התוכנית עוצרת ונפתח פרומפט אינטראקטיבי בטרמינל, בדיוק כמו שורת הפקודה של פייתון הרגילה, רק שעכשיו יש לכם גישה לכל המשתנים המקומיים באותה נקודה בדיוק.

הפקודות הבסיסיות שכדאי לדעת

אין צורך לזכור עשרות פקודות, חמש או שש מספיקות בשביל רוב הדיבוגים:

  • n (next) - מריץ את השורה הנוכחית ועובר לשורה הבאה, בלי להיכנס לתוך פונקציות שנקראות בדרך.
  • s (step) - כמו n, אבל אם השורה קוראת לפונקציה אחרת, נכנסים פנימה אליה.
  • c (continue) - ממשיכים להריץ עד לנקודת עצירה הבאה, או עד סוף התוכנית.
  • l (list) - מציג את הקוד סביב השורה הנוכחית, כדי להתמצא איפה בדיוק אתם נמצאים.
  • p (print) - מדפיס ערך של משתנה או ביטוי, למשל p a מדפיס את הערך של המשתנה a.
  • q (quit) - יוצא מהדיבאגר ועוצר את הריצה.

דוגמה מלאה - איתור באג

נניח שיש לכם פונקציה שאמורה לחשב ממוצע של רשימת מספרים, אבל היא מחזירה תוצאה שגויה:

def average(numbers):
    total = 0
    count = 0
    for n in numbers:
        total += n
    return total / count

breakpoint()
result = average([10, 20, 30])

מריצים את הקובץ, מגיעים לעצירה, ומקישים s כדי להיכנס לתוך הפונקציה average. עכשיו אפשר להקיש n כמה פעמים כדי לעבור שורה אחר שורה בתוך הלולאה, ולבדוק אחרי כל שורה עם p total ו-p count מה הערכים בפועל. תוך כמה שניות תגלו את הבעיה - המשתנה count לא מתעדכן אף פעם בתוך הלולאה, ולכן החלוקה בסוף היא חלוקה באפס. זה בדיוק סוג הבאג שקל לפספס בקריאה רגילה של הקוד, אבל קופץ מיד כשעוברים איתו שורה אחר שורה בדיבאגר.

מה עם עורכי הקוד

VS Code ו-PyCharm, שני העורכים הכי נפוצים, מגיעים עם דיבאגר גרפי מובנה - אפשר ללחוץ ליד מספר שורה כדי לסמן נקודת עצירה, ואז לראות את כל המשתנים בפאנל צדדי בלי להקליד שום פקודה. זה נוח מאוד, ורוב המפתחים המנוסים עובדים ככה ביומיום. אבל שווה להכיר גם את pdb עצמו, כי הוא זמין בכל מקום שיש פייתון מותקן, גם על שרת מרוחק בלי עורך גרפי, וגם כי הבנת הפקודות הבסיסיות עוזרת להבין מה בדיוק קורה מתחת למכסה כשלוחצים על הכפתורים היפים בעורך.

אם אתם עדיין בשלבים הראשונים ומרגישים שאתם מתמודדים עם באגים בלי שיטה סדורה, שווה לחזור אחורה ולחזק את היסודות בקורס התכנות הבסיסי שלנו, שם בונים הרגלי דיבוג נכונים כבר מהתרגילים הראשונים.

לסיכום

pdb לא מחליף חשיבה, אבל הוא נותן לכם דרך הרבה יותר יעילה לחקור מה קורה בקוד שלכם בזמן אמת, במקום לנחש עם print אינסופיים. תתחילו להשתמש ב-breakpoint בפעם הבאה שאתם נתקעים, ותראו כמה מהר זה מקצר את זמן הדיבוג.

הצטרפו לקהילה בדיסקורד