How to do conditional compilation in Python ?
Is it using DEF ?
There is actually a way to get conditional compilation, but it's very limited.
if __debug__:
doSomething()
The __debug__
flag is a special case. When calling python with the -O
or -OO
options, __debug__
will be false, and the compiler will ignore that statement. This is used primarily with asserts, which is why assertions go away if you 'really compile' your scripts with optimization.
So if your goal is to add debugging code, but prevent it from slowing down or otherwise affecting a 'release' build, this does what you want. But you cannot assign a value to __debug__
, so that's about all you can use it for.
Python isn't compiled in the same sense as C or C++ or even Java, python files are compiled "on the fly", you can think of it as being similar to a interpreted language like Basic or Perl.1
You can do something equivalent to conditional compile by just using an if statement. For example:
if FLAG:
def f():
print "Flag is set"
else:
def f():
print "Flag is not set"
You can do the same for the creation classes, setting of variables and pretty much everything.
The closest way to mimic IFDEF would be to use the hasattr function. E.g.:
if hasattr(aModule, 'FLAG'):
# do stuff if FLAG is defined in the current module.
You could also use a try/except clause to catch name errors, but the idiomatic way would be to set a variable to None at the top of your script.
Doesn't make much sense in a dynamic environment. If you are looking for conditional definition of functions, you can use if
:
if happy:
def makemehappy():
return "I'm good"
You could use the method discussed here: Determine if variable is defined in Python as a substitute for #ifdef
Use pypreprocessor
Which can also be found on PYPI (Python Package Index) and can be fetched using pip.
The basic example of usage is:
from pypreprocessor import pypreprocessor
pypreprocessor.parse()
#define debug
#ifdef debug
print('The source is in debug mode')
#else
print('The source is not in debug mode')
#endif
You can also output the postprocessed code to a file by specifying...
pypreprocessor.output = 'output_file_name.py'
anywhere between the pypreprocessor import and the call to parse().
The module is essentially the python implementation of C preprocessor conditional compilation.
SideNote: This is compatible with both python2x and python 3k
Disclaimer: I'm the author of pypreprocessor
Update:
I forgot to mention before. Unlike the if
/else
or if _debug:
approaches described in other answers, this is a true preprocessor. The bytecode produced will not contain the code that is conditionally excluded.
Python compiles a module automatically when you import it, so the only way to avoid compiling it is to not import it. You can write something like:
if some_condition:
import some_module
But that would only work for complete modules. In C and C++ you typically use a preprocessor for conditional compilation. There is nothing stopping you from using a preprocessor on your Python code, so you could write something like:
#ifdef SOME_CONDITION
def some_function():
pass
#endif
Run that through a C preprocessor and you'd have real conditional compilation and some_function
will only be defined if SOME_CONDITION
is defined.
BUT (and this is important): Conditional compilation is probably not what you want. Remember that when you import a module, Python simply executes the code in it. The def and class statements in the module are actually executed when you import the module. So the typical way of implementing what other languages would use conditional compilation for is just a normal if statement, like:
if some_condition:
def some_function():
pass
This will only define some_function
if some_condition
is true.
It's stuff like this that makes dynamic languages so powerful while remaining conceptually simple.