my python code is interlaced with lots of function calls used for (debugging|profiling|tracing etc.) for example:
import logging
logging.root.setLevel(logging.DEBUG)
logging.debug('hello')
j = 0
for i in range(10):
j += i
logging.debug('i %d j %d' % (i,j))
print(j)
logging.debug('bye')
i want to #define these resource consuming functions out of the code. something like the c equivalent
#define logging.debug(val)
yes, i know the logging module logging level mechanism can be used to mask out loggings below set log level. but, im asking for a general way to have the python interpreter skip functions (that take time to run even if they dont do much)
one idea is to redefine the functions i want to comment out into empty functions:
def lazy(*args): pass
logging.debug = lazy
the above idea still calls a function, and may create a myriad of other problems
Python's "object-based" subset is roughly equivalent to JavaScript. Like JavaScript (and unlike Java), Python supports a programming style that uses simple functions and variables without engaging in class definitions. However, for JavaScript, that's all there is.
The 'in' Operator in Python The in operator works with iterable types, such as lists or strings, in Python. It is used to check if an element is found in the iterable. The in operator returns True if an element is found. It returns False if not.
Python does not have a preprocessor, although you could run your python source through an external preprocessor to get the same effect - e.g. sed "/logging.debug/d"
will strip out all the debug logging commands. This is not very elegant though - you will end up needing some sort of build system to run all your modules through the preprocessor and perhaps create a new directory tree of the processed .py files before running the main script.
Alternatively if you put all your debug statements in an if __debug__:
block they will get optimised out when python is run with the -O (optimise) flag.
As an aside, I checked the code with the dis module to ensure that it did get optimised away. I discovered that both
if __debug__: doStuff()
and
if 0: doStuff()
are optimised, but
if False: doStuff()
is not. This is because False is a regular Python object, and you can in fact do this:
>>> False = True
>>> if False: print "Illogical, captain"
Illogical, captain
Which seems to me a flaw in the language - hopefully it is fixed in Python 3.
Edit:
This is fixed in Python 3: Assigning to True or False now gives a SyntaxError.
Since True and False are constants in Python 3, it means that if False: doStuff()
is now optimised:
>>> def f():
... if False: print( "illogical")
...
>>> dis.dis(f)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE
Although I think the question is perfectly clear and valid (notwithstanding the many responses that suggest otherwise), the short answer is "there's no support in Python for this".
The only potential solution other than the preprocessor suggestion would be to use some bytecode hacking. I won't even begin to imagine how this should work in terms of the high-level API, but at a low level you could imagine examining code objects for particular sequences of instructions and re-writing them to eliminate them.
For example, look at the following two functions:
>>> def func():
... if debug: # analogous to if __debug__:
... foo
>>> dis.dis(func)
2 0 LOAD_GLOBAL 0 (debug)
3 JUMP_IF_FALSE 8 (to 14)
6 POP_TOP
3 7 LOAD_GLOBAL 1 (foo)
10 POP_TOP
11 JUMP_FORWARD 1 (to 15)
>> 14 POP_TOP
>> 15 LOAD_CONST 0 (None)
18 RETURN_VALUE
Here you could scan for the LOAD_GLOBAL
of debug
, and eliminate it and everything up to the JUMP_IF_FALSE
target.
This one is the more traditional C-style debug() function that gets nicely obliterated by a preprocessor:
>>> def func2():
... debug('bar', baz)
>>> dis.dis(func2)
2 0 LOAD_GLOBAL 0 (debug)
3 LOAD_CONST 1 ('bar')
6 LOAD_GLOBAL 1 (baz)
9 CALL_FUNCTION 2
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
Here you would look for LOAD_GLOBAL
of debug
and wipe everything up to the corresponding CALL_FUNCTION
.
Of course, both of those descriptions of what you would do are far simpler than what you'd really need for all but the most simplistic patterns of use, but I think it would be feasible. Would make a cute project, if nobody's already done it.
Well, you can always implement your own simple preprocessor that does the trick. Or, even better, you can use an already existing one. Say http://code.google.com/p/preprocess/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With