Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes
Python

How to Debug Python Like a Pro

Stop relying on print() statements and learn to use Python's built-in debugger pdb and breakpoint() to inspect variables, step through code, and fix bugs faster.

July 2026 4 min read 2 views 0 hearts

Debugging is something every Python developer has to do, but too many people rely on scattering print() statements everywhere and hoping for the best. It works, sure, but it's slow, messy, and honestly, it makes you look like a beginner.

If you want to level up, there are much smarter ways to track down bugs — and they don't require any special tools beyond what's already in Python. Here's how you start debugging like someone who actually knows what they're doing.

Use pdb Instead of Sticking print() Everywhere

pdb is Python's built-in debugger, and it's a game changer. Instead of guessing what your variables hold, you can pause execution right at the problem spot and inspect everything live.

Just add this one line where you want to stop:

import pdb; pdb.set_trace()

When Python hits that line, it drops you into an interactive shell. You can type variable_name to see its value, n to step to the next line, c to continue running, or q to quit. It's like having a microscope for your code.

For example, let's say you have a function that's returning unexpected results:

def calculate_discount(price, customer_type):
    import pdb; pdb.set_trace()
    if customer_type == "vip":
        return price * 0.8
    elif customer_type == "regular":
        return price * 0.9
    else:
        return price

When you call calculate_discount(100, "premium"), Python will stop at that line. You can check price is 100, customer_type is "premium", and see exactly what the function returns — maybe you'll notice there's no case for "premium"! That's way faster than adding prints everywhere and rerunning.

Python 3.7+ Has breakpoint() — Use It

If you're using Python 3.7 or newer, you don't even need the import pdb part. Just call breakpoint() anywhere in your code:

def process_data(data):
    breakpoint()  # Automatically drops into pdb
    # Your logic here

It does the exact same thing as pdb.set_trace(), but it's shorter and cleaner. Plus, you can control what debugger it uses by setting the PYTHONBREAKPOINT environment variable — so you can switch to more advanced tools like ipdb if you want.

Log Smarter, Not Harder

Print debugging isn't all bad — sometimes you just need to track what's happening over time. But print() is noisy and unsophisticated. Instead, use Python's logging module:

import logging

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

def fetch_user(user_id):
    logging.debug(f"Fetching user {user_id}")
    # Your database code
    logging.info(f"User {user_id} fetched successfully")

The huge advantage here is you can set different log levels (DEBUG, INFO, WARNING, ERROR). In development, you see everything. In production, you only see warnings and errors — no spam. Plus, you can save logs to a file instead of stdout, which is a lifesaver for debugging issues that only happen after your code has been running for hours.

Set Exception Breakpoints to Catch the Real Problem

Sometimes you get an exception and you have no idea what caused it. Instead of wrapping everything in try/except blocks and trying to reproduce the bug, use the -m pdb flag when running your script from the terminal:

python -m pdb my_script.py

This starts your script under pdb. When an exception happens, Python will stop right there, and you can inspect variables and the call stack. Type where to see the full traceback, and u or d to move up and down the stack frames. It's like rewind for bugs — you can see exactly the state when things went wrong.

A Real-World Example That Puts It All Together

Let's say you're working on an e-commerce site built by Pythonskillset — imagine a checkout function that's giving wrong totals. Instead of guessing, you drop in a breakpoint:

def checkout(cart, user):
    breakpoint()
    total = 0
    for item in cart:
        total += item.price * item.quantity
    if user.is_vip:
        total *= 0.9
    # Some discount logic happens here
    return total

When you run the test case, the debugger opens. You can check cart — oh, it's a list of dictionaries, but the function expects items with .price and .quantity attributes. There's your bug. You step through the loop and see item.price raises an AttributeError. Fix the data structure or the loop logic, and you're done in minutes instead of hours.

Stop Being Afraid of the Debugger

Most developers avoid pdb because they think it's complicated or only for "real" programmers. The truth is, it's one of the simplest tools in Python, and once you start using it, you'll wonder how you ever lived without it. Print debugging is like using a map — pdb is like having GPS. It shows you exactly where you are and what's around you.

So next time you hit a bug, resist the urge to type print(). Type breakpoint() instead. Your future self will thank you.

Comments

Questions, corrections, and tips stay visible for everyone reading this page.

0 in thread

Join the discussion

Shown next to your comment.

Up to 4,000 characters

No comments yet

Be the first to leave a note — it helps the next reader.