如何用逗号作为千位分隔符记录数字?
How to log number with commas as thousands separators?
是时候将所有打印件转换为我正在维护的库中的记录调用了。一些打印调用使用 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 日志记录模块所需的 % 格式化语法时,如何指定千位分隔符?
目前正在使用此解决方法,它确实提供了所需的输出,但似乎是错误的,因为变量首先使用 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!
这是 logging
的一个限制,它实际上在 documentation:
中(至少有一处)提到过
logging.debug(msg, *args, **kwargs)
Logs a message with level DEBUG
on the root logger. The msg is the message format string, and the args are the arguments which are merged into msg
using the string formatting operator. (Note that this means that you can use keywords in the format string, together with a single dictionary argument.)
(强调我的)
但是字符串格式运算符%
不支持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__:
this bird wouldn't voom if you put 4,000,000 volts through it!
这实际上是从 "Use of alternative formatting styles" 部分的最后一个示例中逐字复制的(我只是更改了消息)。
就我个人而言,我会选择您的 format(n, ',')
解决方案。它可能并不完美,但不需要设置自定义 LoggerAdapter
来打印不同的千位分隔符。
是时候将所有打印件转换为我正在维护的库中的记录调用了。一些打印调用使用 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 日志记录模块所需的 % 格式化语法时,如何指定千位分隔符?
目前正在使用此解决方法,它确实提供了所需的输出,但似乎是错误的,因为变量首先使用 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!
这是 logging
的一个限制,它实际上在 documentation:
logging.debug(msg, *args, **kwargs)
Logs a message with level
DEBUG
on the root logger. The msg is the message format string, and the args are the arguments which are merged intomsg
using the string formatting operator. (Note that this means that you can use keywords in the format string, together with a single dictionary argument.)
(强调我的)
但是字符串格式运算符%
不支持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__:
this bird wouldn't voom if you put 4,000,000 volts through it!
这实际上是从 "Use of alternative formatting styles" 部分的最后一个示例中逐字复制的(我只是更改了消息)。
就我个人而言,我会选择您的 format(n, ',')
解决方案。它可能并不完美,但不需要设置自定义 LoggerAdapter
来打印不同的千位分隔符。