[Python-ideas] Efficient debug logging

Steven D'Aprano steve at pearwood.info
Wed Feb 15 06:18:31 EST 2017

On Tue, Feb 14, 2017 at 03:51:05PM +0000, Barry Scott wrote:
> A common pattern I use is to have logging calls for debug and information with my applications.
> The logging calls can be separately enabled and disabled.
> What would be nice is to be able to avoid evaluation the tuple of arguments if debug is
> disabled as this can be expensive. I can write this:
> 	if debug_log_enabled:  debugLog( ‘info is %r’ % (expensiveFunction(),) )
> But that is a more code then I would like to write. And if the debug code is a performance problem cannot
> be left in the production code.

Occasionally people (often me... :-) will suggest that it would be good 
if Python had some sort of lightweight "thunk" for delayed evaluation. I 
don't have good syntax for that, but let's pretend it was "<# ... #>" 
just for the sake of having a way to talk about it.

We can think of a thunk as being something like syntax for lazy 
evaluation, so you could write:

debugLog( ‘info is %r’ % (<#expensiveFunction()#>, ) )

and the expensive function call would only actually be made if it was 

Python doesn't have thunks, but there is a relatively heavyweight 
solution for delayed evaluation: wrap the code in a function.

debugLog( ‘info is %r’, lambda: expensiveFunction() )

and then adjust debugLog so that if the argument is a function, it will 
call the function only when needed:

def debugLog(message, value):
    if debug_log_enabled:
        if isinstance(value, types.FunctionType):
            value = value()
        log(message % value)

> But I’d like to only write:
> 	dbg_log( ‘a debug message’ )
> And have the evaluation of the argument skipped unless its dbg_log is enabled.

Indeed. That's what thunks could give us, if only we had a clear picture 
of how they would work, when they would be evaluated, and what syntax 
they should use.

In the meantime, there are other solutions, not as (hypothetically) 
lightweight, but they'll work *now* rather than needing to wait for 
Python 3.7 or 3.9 or 4.5 :-)

But if you have some good, concrete suggestions for how to do thunks in 
Python, please tell us!


More information about the Python-ideas mailing list