我是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风格有什么好处吗?
答案 0 :(得分:2)
多参数样式延迟了格式化的时刻。这使得日志记录模块的其他部分有机会在最终格式化之前对这些参数进行操作,甚至只是选择忽略该调用。
作为Charles Duffy points out,logging flow diagram的第一步是检查记录器是否已启用呼叫级别。如果未启用日志记录级别,则甚至不会创建LogRecord。因此,延迟格式化可以在这些情况下保存程序计算周期。
此延迟的另一个可能用途是logging.Filter
s可以在格式化之前处理参数:
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
请注意,参数brillig
和toves
被ContextFilter
大写并间隔开。如果logger.info
仅接受预先格式化的字符串,则无法执行此操作(在调用{{1}之前,不强迫用户执行ContextFilter
的工作})。
过滤器也可以用来(惊喜!)在记录被发出之前过滤掉(通过返回logger.info
而不是False
)。延迟格式化允许True
检查并可能根据参数值过滤掉记录。因此,在不需要时可以完全避免字符串格式化。
答案 1 :(得分:0)
这不是关于字符串格式化,而是关于将参数传递给方法。
方法logging.info
及其相关方法logging.debug
,logging.warning
,logging.error
等采用以下参数:
logging.info(msg, *args, **kwargs)
这意味着msg
是必需的位置参数。在第一个示例中,您只传递一个参数:
"This is a %s" % "test" # msg
在你的另一个例子中,你传递了两个参数:
"This is a %s" # msg
"test" # *args
在第一个示例中,您手动执行该方法可以为您完成的工作。