恕我直言,对于很可能会显示的消息,例如那些给予error
或warn
没有太大区别的消息。
对于不太可能显示的消息,我肯定会选择第二个版本,主要是出于性能原因。我经常将大对象作为参数传递给info
,它实现了一种代价高昂的__str__
方法。显然,发送这个预先格式化的文件info
会浪费性能。
更新
我刚刚检查了logging
模块的源代码,实际上,格式化是在检查日志级别后完成的。例如:
class Logger(Filterer):
# snip
def debug(self, msg, *args, **kwargs):
# snip
if self.isenabledfor(debug):
self._log(debug, msg, args, **kwargs)
可以观察到这一点,msg
并且在调用和检查日志级别args
之间保持不变。log
更新 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
在实践中,这可以提供相当高的性能提升。