Python记录器的C风格与Python风格的字符串格式

时间:2018-02-07 19:19:25

标签: python logging

我是Django的新手并且一直在玩伐木。在我看来,以下info()语句基本上是等同的:

log = logging.getLogger(__name__)
.
.
.
    log.info("This is a %s" % "test")  # Python style
    log.info("This is a %s", "test")   # C style

有什么区别吗?就个人而言,我一直都喜欢能够在任何地方使用Python风格的格式,我倾向于坚持使用这种方法。 Python格式化还有很多,所以看起来更强大。为什么Django会给我们选择?使用C风格有什么好处吗?

2 个答案:

答案 0 :(得分:2)

多参数样式延迟了格式化的时刻。这使得日志记录模块的其他部分有机会在最终格式化之前对这些参数进行操作,甚至只是选择忽略该调用。

作为Charles Duffy points outlogging flow diagram的第一步是检查记录器是否已启用呼叫级别。如果未启用日志记录级别,则甚至不会创建LogRecord。因此,延迟格式化可以在这些情况下保存程序计算周期。

此延迟的另一个可能用途是logging.Filters可以在格式化之前处理参数:

import logging

class ContextFilter(logging.Filter):
    def filter(self, record):
        for key in record.args:
            record.args[key] = ' '.join(record.args[key].upper())
        return True

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
filt = ContextFilter()
logger.addFilter(filt)

logger.info("'Twas %(adj)s, and the slithy %(noun)s", {'adj': 'brillig', 'noun': 'toves'})

日志

INFO:__main__:'Twas B R I L L I G, and the slithy T O V E S

请注意,参数brilligtovesContextFilter大写并间隔开。如果logger.info仅接受预先格式化的字符串,则无法执行此操作(在调用{{1}之前,不强迫用户执行ContextFilter 的工作})。

过滤器也可以用来(惊喜!)在记录被发出之前过滤掉(通过返回logger.info而不是False)。延迟格式化允许True检查并可能根据参数值过滤掉记录。因此,在不需要时可以完全避免字符串格式化。

答案 1 :(得分:0)

这不是关于字符串格式化,而是关于将参数传递给方法。

方法logging.info及其相关方法logging.debuglogging.warninglogging.error等采用以下参数:

logging.info(msg, *args, **kwargs)

这意味着msg是必需的位置参数。在第一个示例中,您只传递一个参数:

"This is a %s" % "test" # msg

在你的另一个例子中,你传递了两个参数:

"This is a %s" # msg
"test" # *args

在第一个示例中,您手动执行该方法可以为您完成的工作。