Movatterモバイル変換
[0]ホーム
[Python-ideas] Efficient debug logging
Abe Dillonabedillon at gmail.com
Tue Feb 14 17:20:24 EST 2017
There are several mechanisms in the logging module to handle this use-case.First, note that logging functions can take multiple arguments (https://docs.python.org/3/library/logging.html?highlight=logging#logging.Logger.debug):>>> import logging>>> msg = "hello, %s! %s to %s you!">>> args = ("world", "pleased", "meet")>>> logging.warning(msg, *args)WARNING:root:hello, world! pleased to meet you!None of the string formatting will take place if the log call is below thelevel of the logger. It might be worth while to add a class that stores anunevaluated function, then evaluates the function when __str__ or __repr__is called:>>> class MessageFunction:... def __init__(self, func, *args, **kwargs):... self.func = func... self.args = args... self.kwags = kwargs... def __str__(self):... return str(self.func(*self.args, **self.kwargs))... def __repr__(self):... return repr(self.func(*self.args, **self.kwargs))>>> import logging>>> logging.debug("result = %s", MessageFunction(expensive_func, *args,**kwargs))You can also add Filters to your logger:https://docs.python.org/3/library/logging.html?highlight=logging#logging.FilterOn Tue, Feb 14, 2017 at 11:51 AM, MRAB <python at mrabarnett.plus.com> wrote:> On 2017-02-14 15:51, 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.>>>> For example:>>>> debug_log_enabled = False>> def debugLog( msg ):>> If debug_log_enabled:>> print( ‘Debug: %s’ % (msg,) )>>>> Then the caller can simple write:>>>> def main():>> debugLog( ‘Start of main’ )>>>> This is fine until the evaluation of the msg becomes expensive.>>>> debugLog( ‘info is %r’ % (expensiveFunction(),) )>>>> 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.>>>> I could combine the boolean and the log function by using a class to tidy>> up the implementation.>>>> class DebugLog:>> def __init__( self, enabled = False ):>> self.enabled = enabled>>>> def __bool__( self ):>> return self.enabled>>>> def __call__( self, msg ):>> if self.enabled: print( ‘Debug: %s’ % (msg,) )>>>> And call like this:>>>> dbg_log = DebugLog()>>>> If dbg_log: dbg_log( ‘a debug message’ )>>>> 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.>>>> I cannot see how to do this with python as it stands.>>>> Something would have to be added to allow python to short circuit the>> argument tuple evaluation.>>>> Maybe python can check for a special dunder on the class that know how to>> do this idiom, __if_true_call__?>>>> Thoughts?>>>> You could let your debugging function accept a callable and use lambda to> delay execution:>> def debugLog(msg):> if debug_log_enabled:> if callable(msg):> msg = msg()>> print('Debug: %s' % (msg, ))>>> debugLog('Start of main')>> debugLog(lambda: 'info is %r' % (expensiveFunction(), ))>>> _______________________________________________> Python-ideas mailing list>Python-ideas at python.org>https://mail.python.org/mailman/listinfo/python-ideas> Code of Conduct:http://python.org/psf/codeofconduct/>-------------- next part --------------An HTML attachment was scrubbed...URL: <http://mail.python.org/pipermail/python-ideas/attachments/20170214/2b4aaf35/attachment-0001.html>
More information about the Python-ideasmailing list
[8]ページ先頭