How do you implement “#ifdef” in python?

If you just want to disable logging methods, use the logging module. If the log level is set to exclude, say, debug statements, then logging.debug will be very close to a no-op (it just checks the log level and returns without interpolating the log string).

If you want to actually remove chunks of code at bytecode compile time conditional on a particular variable, your only option is the rather enigmatic __debug__ global variable. This variable is set to True unless the -O flag is passed to Python (or PYTHONOPTIMIZE is set to something nonempty in the environment).

If __debug__ is used in an if statement, the if statement is actually compiled into only the True branch. This particular optimization is as close to a preprocessor macro as Python ever gets.

Note that, unlike macros, your code must still be syntactically correct in both branches of the if.


To show how __debug__ works, consider these two functions:

def f():
    if __debug__: return 3
    else: return 4

def g():
    if True: return 3
    else: return 4

Now check them out with dis:

>>> dis.dis(f)
  2           0 LOAD_CONST               1 (3)
              3 RETURN_VALUE        
>>> dis.dis(g)
  2           0 LOAD_GLOBAL              0 (True)
              3 JUMP_IF_FALSE            5 (to 11)
              6 POP_TOP             
              7 LOAD_CONST               1 (3)
             10 RETURN_VALUE        
        >>   11 POP_TOP             

  3          12 LOAD_CONST               2 (4)
             15 RETURN_VALUE        
             16 LOAD_CONST               0 (None)
             19 RETURN_VALUE        

As you can see, only f is “optimized”.

Leave a Comment