【问题标题】:Python logging new style format stringPython记录新样式格式字符串
【发布时间】:2021-03-31 14:42:43
【问题描述】:

我正在使用带有日志库的 Python 3.8.8。为了在 Python 中有一个通用的字符串格式,我还想用{} 记录新的格式字符串变体。我还想对日志字符串使用惰性求值(所以没有"{}".format(var)f"{var}")。

根据this Stack Overflow 关于 pylint 的帖子(所以 pylint logging-format-style=new),以下变体应该可以工作。但是,logging.info 有一个例外。

import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()

var1 = "foo"
var2 = "blub"

logger.info("var1 {}, var2 {}", var1, var2) # Exception thrown!

最后一行的异常如下:

--- Logging error ---
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/logging/__init__.py", line 1081, in emit
    msg = self.format(record)
  File "/usr/local/lib/python3.8/logging/__init__.py", line 925, in format
    return fmt.format(record)
  File "/usr/local/lib/python3.8/logging/__init__.py", line 664, in format
    record.message = record.getMessage()
  File "/usr/local/lib/python3.8/logging/__init__.py", line 369, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting

我从异常消息中推断,日志记录仍然需要使用 %s 的旧样式格式。

如何在登录 Python 3.8.8 时使用带有 {} 的新格式字符串变体 使用任何额外的包装函数(正如 Stack Overflow 上的其他一些帖子所建议的那样)?虽然可以在 pylint 中定义,但如果没有任何包装函数,这可能是不可能的吗?

【问题讨论】:

  • 这能回答你的问题吗? Logging variable data with new format string
  • @jonrsharpe 感谢that post 的建议。在问这个问题之前,我已经看过了,但这并没有回答我的问题,因为首先,它是 Python 2.7,其次,它使用了一些包装函数,并且已经使用了 Python 3.8,我希望不再需要。
  • 我发布的引用来自 3.latest 文档,它并没有突然变成现有的日志调用使用 %.您不喜欢这些答案的事实并不意味着它们不是答案。
  • @jonrsharpe 我的第一条评论是对您第一条评论的回答。到目前为止,我没有时间从日志记录文档中查看您的报价的更详细信息,但我现在检查了它。确实,我希望从 2.7 到 3.8 已经有一些变化,但对我来说,知道这仍然不起作用,这也是一个完全有效且可以接受的答案。随意写这个作为问题的答案,我会接受。否则我会自己写下我的问题的答案。

标签: python-3.x python-logging


【解决方案1】:

我认为 Python 字符串插值更容易使用:

logger.info(f"var1 {var1}, var2 {var2}") 

实现lazy evaluation

if logger.isEnabledFor(logging.INFO):
    logger.info(f"var1 {var1}, var2 {var2}") 

【讨论】:

  • 这忽略了问题的全部要点。将未插值的字符串传递给logger.X 将仅在字符串被发射时插入该字符串
  • 没有。下一个最好的事情是继续使用%s 或创建自定义样式:stackoverflow.com/questions/13131400/…
  • OP 没有提到需要延迟评估
  • @MikeSlinn 谢谢你的建议。你是对的,我没有提到懒惰的评价,但这是我想要的。我已经更新了我的问题。关于您的回答,是的,它有效,但对我来说,使用 logger.isEnabledFor 听起来不像是一个优雅的解决方案,而是更像是一种解决方法(尤其是如果不仅有一条日志消息,而且可能有很多)
  • @Fabian,您可以将启用状态缓存在 var e = logger.isEnabledFor(logging.INFO) 中,然后使用类似 e and logger.info(f"var1 {var1}, var2 {var2}") 的布尔快捷逻辑。如果e 为假,则不会评估其余部分。
猜你喜欢
  • 1970-01-01
  • 2022-11-23
  • 2012-10-19
  • 2019-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多