This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.
If this question can be reworded to fit the rules in the help center, please edit the question.

If you are developing a web application, add a view for myserver.com/pdb in debug mode that simply does import pdb; pdb.set_trace(). If you are using Flask/Werkzeug that has an interactive debugger, you can also have a view that just does assert False.
–
osaSep 28 '14 at 2:32

Its goal is to provide all the niceties of modern GUI-based debuggers in a more lightweight and keyboard-friendly package. PuDB allows you to debug code right where you write and test it – in a terminal. If you've worked with the excellent (but nowadays ancient) DOS-based Turbo Pascal or C tools, PuDB's UI might look familiar.

The logging module lets you specify a level of importance; during debugging you can log everything, while during normal operation you might only log critical things. You can switch things off and on.

Most people just use basic print statements to debug, and then remove the print statements. It's better to leave them in, but disable them; then, when you have another bug, you can just re-enable everything and look your logs over.

This can be the best possible way to debug programs that need to do things quickly, such as networking programs that need to respond before the other end of the network connection times out and goes away. You might not have much time to single-step a debugger; but you can just let your code run, and log everything, then pore over the logs and figure out what's really happening.

The problem with logging module is that it heavily breaks with Unicode and various workarounds are needed to have it working within an internationalized applications. Though, this is still the best logging solution for Python.
–
Jacek KoniecznyFeb 26 '10 at 12:15

It is possible to print what Python lines are executed (thanks Geo!). This has any number of applications, for example, you could modify it to check when particular functions are called or add something like ## make it only track particular lines.

True, but logging has to be set up. I will learn how to use the module after honors
–
CasebashOct 29 '09 at 9:06

print can be useful for simple cases and especially when developing projects with small startup time. On the other side it can be addictive and using it over pdb or any other debugger in more complex scenarios will usually cause you headaches
–
viniliosNov 27 '11 at 0:44

PyDev has a pretty good interactive debugger. It has watch expressions, hover-to-evaluate, thread and stack listings and (almost) all the usual amenities you expect from a modern visual debugger. You can even attach to a running process and do remote debugging.

Like other visual debuggers, though, I find it useful mostly for simple problems, or for very complicated problems after I've tried everything else. I still do most of the heavy lifting with logging.

Does it have the ability to edit and continue?
–
CasebashOct 26 '09 at 6:40

@CaseBash no it doesn't but that feature is planned. Even without it though, the speed and ease of setting/unsetting breakpoints and looking through variable values is still very useful
–
JiaaroOct 26 '09 at 12:50

+1 This is the only python debugger that I've found so far that can handle multi-threading.
–
Lee NethertonAug 15 '12 at 13:20

Be careful with its "handling" of multi-threading - any exception in any thread causes the entire process to freeze. Not a bad thing if you're aware of it, very painful if you're not
–
Walt WSep 10 '13 at 21:25

The project looks dead as of april 2014
–
Alojz JanezApr 20 '14 at 7:38

Defining useful repr() methods for your classes (so you can see what an object is) and using repr() or "%r" % (...) or "...{0!r}..".format(...) in your debug messages/logs is IMHO a key to efficient debugging.

Also, the debuggers mentioned in other answers will make use of the repr() methods.