如何使用 % 格式在日志记录中指定变量的浮点精度?

How to specify float precision from variable in logging using % formatting?

我想避免在日志记录中急于求值 f 字符串,因此我使用 %-formatting。

精度由变量定义precision

import logging
value = 3.14159
logging.error("%.2f", value)

precision = 2

logging.error(f"{value:.{precision}f}") # OK but eager evaluation
logging.error("%.*f", value, precision) # fails
logging.error("%.%if", value, precision) # fails

有什么建议吗?

logging.error("%.*f", value, precision) # fails

几乎是正确的,但是精度要先来:

logging.error("%.*f", precision, value) # works

助记符:表示精度的占位符 *float 值的占位符 f 之前,因此精度在 float.[=29 之前提供=]


遗憾的是,虽然助记符适用于其他格式化工具,但它适用于每个占位符的开头,而不是结尾。例如,在 str.format 中,占位符的自动编号是基于每个占位符的左大括号 { 的顺序,因此对于这种情况,您可以这样做:

'{:.{}f}'.format(value, precision)

因为 value 占位符的左大括号位于精度的左大括号占位符之前。当然,在那种情况下,你可以通过明确和编号来避免歧义:

'{0:.{1}f}'.format(value, precision)

或命名它们:

'{value:.{precision}f}'.format(precision=precision, value=value)  # Order of kwargs irrelevant

当然,对于 f-strings,您可以内联每个地方使用的名称,因此不存在混淆:

f'{value:.{precision}f}'

而且它比现代 Python 中的任何其他字符串格式化方法都快,因此对于在正常使用中可能实际发出的任何日志,我只坚持使用 f 字符串。即使对于那些 不会 被发出的,记录低于日志记录级别(并且不被发出)的东西的开销也足够高,以至于避免临时 str 在上下文中非常小,除非打开日志记录,否则不会注意到错误的风险足够高,我通常会使用急切的格式,特别是对于像这样更复杂的情况。我肯定被以下形式的代码所困扰:

 logging.debug('%s %s', a, b, c)

无条件执行代码,但从未启用 DEBUG 级日志记录;我第一次需要它来解决问题时,代码由于占位符计数不匹配而中断。类似的问题对于急切的格式化是不可能的,无论是现代的 f-strings 还是不那么现代的 str.format 甚至像 logging.debug('%s %s' % (a, b, c)) 这样的急切的 printf 风格的格式化;即使完全关闭日志记录,您也会看到错误。