在我看来,对于那些很可能被展示的消息,比如给error
或warn
使用的消息,这并没有太大区别。
对于那些不太可能被展示的消息,出于性能方面的考虑,我肯定会选择第二个版本。我经常将大型对象作为info
的参数传递,它们实现了一个昂贵的__str__
方法。显然,将其预先格式化并发送给info
将是一种性能浪费。
更新
我刚刚检查了logging
模块的源代码,确实,在检查日志级别之后进行格式化。例如:
class Logger(Filterer):
def debug(self, msg, *args, **kwargs):
if self.isenabledfor(debug):
self._log(debug, msg, args, **kwargs)
可以观察到在调用log
和检查日志级别之间,msg
和args
没有被改变。
更新2
受Levon启发,让我为具有昂贵的__str__
方法的对象添加一些测试:
$ 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
实际上,这可以显著提高性能。
warn
之前两者都会发生。并不是质疑你所说的,只是想更加好奇地了解一下。 - Levon