📌Free Shipping for all orders over $60. Just add merch to cart. Applied at checkout.

Debugging is an unavoidable part of software development. No matter how skilled you are, bugs will happen—and how efficiently you fix them can make a huge difference in your productivity and sanity.

Python offers powerful debugging tools that can help you track down issues quickly and effectively. However, most developers rely too much on print() debugging, missing out on better debugging techniques that make troubleshooting easier.

This guide covers the best 7 Python debugging techniques to help you fix bugs faster, write cleaner code, and improve your workflow.

Frequently Asked Questions About Python Debugging

Before diving into debugging techniques, let’s address some common debugging-related questions that developers often search for.

What is the best way to debug Python code?

The most effective way to debug Python code is by using Python’s built-in pdb debugger or the breakpoint() function (Python 3.7+). These tools allow you to pause execution and inspect variables interactively, making it easier to identify issues.

How do I debug a Python script without stopping execution?

Instead of using print() statements, use the logging module. It allows you to log debugging messages to a file or console without stopping the program, so you can analyze what’s happening while your script is still running.

Why is using print() for debugging considered bad practice?

Relying on print() for debugging is inefficient because:

  • It clutters your code with unnecessary print statements.
  • You have to rerun the script every time you make a change.
  • It doesn’t provide real-time inspection of variable states.
    Using tools like pdb, logging, or an interactive debugger is a more scalable approach.

How do I debug Python code in Jupyter Notebook?

Jupyter Notebook has built-in debugging features. You can use the %debug magic command after an error occurs to enter a post-mortem debugging session and inspect variable values.

How do I debug a failing test in Python?

Use pytest --pdb when running tests with pytest. This automatically opens an interactive debugger at the point where the test failed, letting you investigate the issue.


Debugging is about understanding how your code behaves and improving efficiency. Below are seven essential Python debugging techniques that will make you a faster, smarter, and more effective problem-solver.

1. Stop Using print(), Start Using pdb

If you’re still relying on print() statements to debug, you’re wasting time rerunning your script every time you change a print statement.

Instead, use Python’s built-in pdb (Python Debugger), which lets you pause execution, inspect variables, and step through code interactively.

How to Use pdb for Debugging

1️⃣ Insert the following line before the issue occurs:

pythonCopyEditimport pdb; pdb.set_trace()

or, in Python 3.7+, simply use:

pythonCopyEditbreakpoint()

2️⃣ Run your script as usual. Execution will pause at the breakpoint, and you can:

  • Type n (next) to execute the next line.
  • Type p variable_name to print a variable’s value.
  • Type c (continue) to resume execution.

This allows real-time debugging without cluttering your code with print() statements.


2. Use Logging for Smarter Debugging

print() statements don’t scale well in large projects. If you’re debugging something complex, use Python’s logging module instead.

Why Logging is Better than print()

✅ Allows different log levels (INFO, DEBUG, WARNING, ERROR).
✅ Saves logs to a file for later analysis.
✅ Can be turned on/off easily without modifying code.

How to Implement Logging in Python

pythonCopyEditimport logging

logging.basicConfig(level=logging.DEBUG, filename="debug.log", filemode="w")

x = 10
logging.debug(f"Debugging: value of x is {x}")
logging.info("Everything is running smoothly.")
logging.warning("This is a warning message.")

Now, instead of spamming print(), all debug messages go to a file, making them easier to track.


3. Debug Faster with IPython & Jupyter Notebook

If you’re working in data science, machine learning, or scripting, restarting your script every time you debug is inefficient.

Instead, use IPython’s interactive debugging tools or Jupyter Notebook’s %debug magic command.

How to Debug in IPython

If an error occurs, type:

pythonCopyEdit%debug

This will open post-mortem debugging, allowing you to inspect variables without restarting the script.

How to Set Breakpoints in Jupyter

Insert this into a Jupyter cell:

pythonCopyEditfrom IPython.core.debugger import set_trace
set_trace()

This works just like pdb but is optimized for Jupyter Notebook.

This method is game-changing for data scientists who need to debug scripts without losing their kernel state.


4. Catch and Handle Exceptions Gracefully

If your script crashes unexpectedly, it’s because uncaught exceptions terminate execution. Instead of letting that happen, use exception handling to debug smarter.

Example: Debugging with Try-Except

pythonCopyEdittry:
    x = 1 / 0  # ZeroDivisionError
except ZeroDivisionError as e:
    print(f"Error occurred: {e}")

Why This Works:

  • Prevents your script from crashing.
  • Gives clear error messages.
  • Can be combined with logging to track errors.

Using Exception Hooks for Global Debugging

If you want to catch all unhandled exceptions, use sys.excepthook:

pythonCopyEditimport sys

def exception_handler(exc_type, exc_value, exc_traceback):
    print(f"Unhandled exception: {exc_value}")

sys.excepthook = exception_handler

This will catch errors globally, making debugging easier in large applications.


5. Use pytest for Debugging Unit Tests

If you’re writing tests with unittest or pytest, debugging failing tests can be annoying—especially when the output doesn’t tell you what went wrong.

With pytest, you can drop into an interactive debugger the moment a test fails:

How to Debug Failing Tests with pytest

bashCopyEditpytest --pdb

This will pause execution where the test fails so you can inspect variables in real time.

Alternatively, inside your test, insert:

pythonCopyEditimport pytest
pytest.set_trace()

Why This Helps:

  • Debug exactly where the test fails instead of rerunning the whole suite.
  • Speeds up troubleshooting for test-driven development.

6. Improve Error Messages with better_exceptions

Python’s default error messages aren’t always the easiest to read, especially when debugging complex issues. The better_exceptions package enhances tracebacks, showing variable values at the time of failure.

How to Install better_exceptions

bashCopyEditpip install better_exceptions

How to Enable it in Your Script

pythonCopyEditimport better_exceptions
better_exceptions.hook()

Why This Works:

  • Shows actual variable values inside stack traces.
  • More readable and informative than default Python tracebacks.

If you’re debugging large, complex applications, better_exceptions makes error messages 10x more useful.


7. Track Memory Usage with tracemalloc

If your Python script uses more memory than expected or crashes due to high memory consumption, you might have a memory leak.

How to Detect Memory Leaks with tracemalloc

pythonCopyEditimport tracemalloc

tracemalloc.start()

# Run your function
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics("lineno")

for stat in top_stats[:5]:  # Show top 5 memory-consuming lines
    print(stat)

Why This Works:

  • Shows which parts of your code consume the most memory.
  • Helps detect inefficient object allocation.

This is especially useful for optimizing large datasets or long-running applications.

Debug Smarter, Not Harder

Debugging doesn’t have to be painful. By using the right Python debugging techniques, you can fix bugs faster, write more reliable code, and improve your development workflow.

Use pdb and breakpoint() for interactive debugging.
Replace print() with logging for structured debugging.
Use %debug and IPython.embed() in Jupyter for real-time debugging.
Enable better_exceptions to improve error messages.
Use tracemalloc to find memory leaks.

🚀 Want to debug in style? Check out MadDosh’s Python-themed debugging mugs, T-shirts, and notebooks to rep your coder mindset!


Leave a Reply

Your email address will not be published. Required fields are marked *