惯用的Python日志记录:格式字符串+ args列表与内联字符串格式-哪个是首选? [英] Idiomatic Python logging: format string + args list vs. inline string formatting - which is preferred?

查看:95
本文介绍了惯用的Python日志记录:格式字符串+ args列表与内联字符串格式-哪个是首选?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用格式字符串+ args列表而不是内联格式来调用日志记录功能是否有利?

Is it advantageous to call logging functions with format string + args list vs. formatting inline?

我已经看到(并编写了)使用内联字符串格式的日志记录代码:

I've seen (and written) logging code that uses inline string formatting:

logging.warn("%s %s %s" % (arg1, arg2, arg3))

,但我认为使用更好(性能上更好,更惯用):

and yet I assume it's better (performance-wise, and more idiomatic) to use:

logging.warn("%s %s %s", arg1, arg2, arg3)

因为第二种形式避免了在调用日志记录功能之前进行字符串格式化操作.如果当前的日志记录级别可以过滤掉日志消息,则无需进行格式化,从而减少了计算时间和内存分配.

because the second form avoids string formatting operations prior to invoking the logging function. If the current logging level would filter out the log message, no formatting is necessary, reducing computing time and memory allocations.

我是在这里吗,还是我错过了什么?

Am I on the right track here, or have I missed something?

推荐答案

恕我直言,对于很有可能显示的消息,例如给errorwarn的消息,没有太大的区别.

IMHO, for messages that are very likely to be displayed, such as those given to error or warn it does not make much of a difference.

对于不太可能显示的消息,我肯定会选择第二个版本,主要是出于性能方面的考虑.我经常将大型对象作为info的参数,以实现昂贵的__str__方法.显然,将这​​种预格式化的文件发送到info将浪费性能.

For messages that are less likely displayed, I would definitely go for the second version, mainly for performance reasons. I often give large objects as a parameter to info, which implement a costly __str__ method. Clearly, sending this pre-formatted to info would be a performance waste.

更新

我刚刚检查了logging模块的源代码,并且确实在检查日志级别之后 完成了格式化.例如:

I just checked the source code of the logging module and, indeed, formatting is done after checking the log level. For example:

class Logger(Filterer):
    # snip
    def debug(self, msg, *args, **kwargs):
        # snip
        if self.isenabledfor(debug):
            self._log(debug, msg, args, **kwargs)

可以看到在调用log和检查日志级别之间未触碰到msgargs.

One can observe that msg and args are untouched between calling log and checking the log level.

更新2

由Levon主持,让我为具有昂贵的__str__方法的对象添加一些测试:

Spired by Levon, let me add some tests for objects that have a costly __str__ method:

$ python -m timeit -n 1000000 -s "import logging" -s "logger = logging.getLogger('foo')" -s "logger.setLevel(logging.ERROR)" "logger.warn('%s', range(0,100))"
1000000 loops, best of 3: 1.52 usec per loop
$ python -m timeit -n 1000000 -s "import logging" -s "logger = logging.getLogger('foo')" -s "logger.setLevel(logging.ERROR)" "logger.warn('%s' % range(0,100))"
1000000 loops, best of 3: 10.4 usec per loop

实际上,这可以大大提高性能.

In practice, this could give a fairly high performance boost.

这篇关于惯用的Python日志记录:格式字符串+ args列表与内联字符串格式-哪个是首选?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆