现在是将所有打印转换为我正在维护的库中的日志记录调用的时候了。一些打印调用正在使用str.format
,如下所示(简化):
>>> n = 4000000
>>> print(f"this bird wouldn't voom if you put {n:,} volts through it!")
this bird wouldn't voom if you put 4,000,000 volts through it!
当我尝试记录它时:
>>> log.warning("this bird wouldn't voom if you put %d, volts through it!", n)
WARNING:root:this bird wouldn't voom if you put 4000000, volts through it!
似乎这没有正确指定千位分隔符。在使用Python的stdlib日志记录模块所需的%-formatting语法时,如何指定千位分隔符?
目前正在使用此解决方法,它确实提供了所需的输出,但似乎错误,因为变量首先使用str.format
格式化,然后再次格式化为字符串,而不是直接记录为数字:
>>> log.warning("this bird wouldn't voom if you put %s volts through it!", format(n, ','))
WARNING:root:this bird wouldn't voom if you put 4,000,000 volts through it!
答案 0 :(得分:2)
这是logging
的限制,并且documentation中的(至少有一个地方)实际提到了这个限制:
logging.debug(msg, *args, **kwargs)
在根记录器上记录级别为
DEBUG
的消息。 msg是消息格式字符串,args是使用字符串格式化运算符合并到msg
的参数。 (请注意,这意味着您可以使用格式字符串中的关键字以及单个字典参数。)
(强调我的)
但字符串格式化运算符%
不支持thousand seperators。
然而,您可以从官方cookbook
:
import logging
class Message(object):
def __init__(self, fmt, args):
self.fmt = fmt
self.args = args
def __str__(self):
return self.fmt.format(*self.args)
class StyleAdapter(logging.LoggerAdapter):
def __init__(self, logger, extra=None):
super(StyleAdapter, self).__init__(logger, extra or {})
def log(self, level, msg, *args, **kwargs):
if self.isEnabledFor(level):
msg, kwargs = self.process(msg, kwargs)
self.logger._log(level, Message(msg, args), (), **kwargs)
logger = StyleAdapter(logging.getLogger(__name__))
def main():
# this changed
logger.warning("this bird wouldn't voom if you put {:,} volts through it!", 4000000)
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
main()
WARNING:__main__:
如果你通过4,000,000伏电压,那只鸟就不会出现这种情况!
这实际上是从"Use of alternative formatting styles"部分的最后一个示例逐字复制(我刚刚更改了消息)。
就个人而言,我会选择你的format(n, ',')
解决方案。它可能不完美,但它不需要设置自定义LoggerAdapter
来打印不同的千位分隔符。