0

in c code I frequently use printf debugging macros like

#define DPRINT_INT(i) fprintf(stderr,"%s has the value %i at line %i", #i,i, __LINE__)

and then i can do things like DPRINT_INT(height) where it will print the variable or things like DPRINT_INT(from_cm_to_inch(get_average(heights))) and it will print out the whole expression for the name.

To do this for python, since python doesn't have c-like macros

I pass a string and use inspect to get the calling functions environment to call eval with. But I don't like passing strings, its ugly and easy to forget(I have it check type and call an exception if it gets passed a non string) and doesn't work as well with the ide.

There isn't any way to extract the variable names and expressions from the python code for the debug function? is there?

Roman A. Taycher
  • 18,619
  • 19
  • 86
  • 141
  • 3
    In Python we tend to write modules that we can [unittest](http://docs.python.org/library/unittest.html) and / or `import` into the REPL and drive them there if necessary. In five years of Python programming I have never used the debugger. – johnsyweb Dec 20 '11 at 09:17
  • I'm not talking about the debugger, though ipython -pdb is nice(debugger on exception in ipython). I'm talking about printf debugging, ie sprinkling debug_print functions over spots in your program, think of it as a quick and dirty alternative to logging – Roman A. Taycher Dec 20 '11 at 09:22
  • 1
    Have you considered http://docs.python.org/library/logging.html#logging.Logger.debug ? – johnsyweb Dec 20 '11 at 09:31
  • 2
    Agreeing with Johnsyweb here: just put in some `logging.debug` statements. The import and configuration of the module is only two lines, plus it gives you the benefit of easily disabling log levels later on without having to change your code. – jro Dec 20 '11 at 09:34

1 Answers1

2

In Python we tend to write modules that we can unittest and / or import into the REPL and drive them there if necessary.

If you can unit-test your functions, you can prove their behaviour for any given input. However, if you must write debug statements, you should use debug() from the standard logging module.

For example:

#!/usr/bin/env python

import logging
import inspect

def buggy_fn():
    d = 42;
    if d != 69:
        logging.debug('%s(%d): %s is not what we expected. [%s]',
                inspect.currentframe().f_back.f_code.co_filename,
                inspect.currentframe().f_back.f_lineno,
                'd',
                repr(d),
                )

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    buggy_fn()

Will output...

DEBUG:root:./buggy.py(19): d is not what we expected. [42]

There's a wealth of useful stuff in inspect that may help you out in your hour of need.

johnsyweb
  • 136,902
  • 23
  • 188
  • 247
  • Is there a way to get it to capture the variable name/expression and print it out? since that is a major part of what I'm going for – Roman A. Taycher Dec 20 '11 at 10:04
  • Johnsyweb is there any way to capture d/variable name/expression name except for string/eval though?(so you don't have to repeat it?). Maybe I should just implement a Eval Log class that subclasses or contains/forwards to a logger? – Roman A. Taycher Dec 28 '11 at 07:09
  • *Most* things are achievable in Python. They're not always a good idea, though. See [this answer](http://stackoverflow.com/a/592849/78845) to [How can you print a variable name in python?](http://stackoverflow.com/questions/592746/how-can-you-print-a-variable-name-in-python) . – johnsyweb Dec 28 '11 at 08:11