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".
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…