Python:记录类型错误:并非所有参数都在字符串格式化期间转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12843099/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:58:46  来源:igfitidea点击:

Python: Logging TypeError: not all arguments converted during string formatting

pythonloggingstring-formatting

提问by daydreamer

Here is what I am doing

这是我在做什么

>>> import logging
>>> logging.getLogger().setLevel(logging.INFO)
>>> from datetime import date
>>> date = date.today()
>>> logging.info('date={}', date)
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 846, in emit
    msg = self.format(record)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 723, in format
    return fmt.format(record)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 464, in format
    record.message = record.getMessage()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 328, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Logged from file <stdin>, line 1
>>> 

My python version is

我的python版本是

$ python --version
Python 2.7.3

How do I make it work?

我如何使它工作?

采纳答案by Matt

You could do the formatting yourself:

您可以自己进行格式化:

logging.info('date={}'.format(date))

As was pointed out by Martijn Pieters, this will always run the string formatting, while using the logging module would cause the formatting to only be performed if the message is actually logged.

正如 Martijn Pieters 所指出的那样,这将始终运行字符串格式化,而使用日志记录模块将导致仅在实际记录消息时才执行格式化。

回答by Martijn Pieters

You cannot use new-style formatting when using the logging module; use %sinstead of {}.

使用日志模块时不能使用新式格式;使用%s代替{}.

logging.info('date=%s', date)

The logging module uses the old-style %operator to format the log string. See the debugmethodfor more detail.

日志模块使用旧式%运算符来格式化日志字符串。有关更多详细信息,请参阅debug方法

If you really want to use str.format()string formatting, consider using custom objects that apply the formatting 'late', when actually converted to a string:

如果您真的想使用str.format()字符串格式,请考虑使用应用格式“late”的自定义对象,当实际转换为字符串时:

class BraceMessage(object):
    def __init__(self, fmt, *args, **kwargs):
        self.fmt = fmt
        self.args = args
        self.kwargs = kwargs

    def __str__(self):
        return self.fmt.format(*self.args, **self.kwargs)

__ = BraceMessage

logging.info(__('date={}', date))

This is an approach the Python 3 loggingmodule documentation proposes, and it happens to work on Python 2 too.

这是Python 3logging模块文档提出的一种方法,它也适用于 Python 2。

回答by Jeff-Meadows

Martijn's answer is correct, but if you prefer to use new style formatting with logging, it can be accomplished by subclassing Logger.

Martijn 的回答是正确的,但如果您更喜欢在日志记录中使用新的样式格式,则可以通过继承 Logger 来实现。

import logging

class LogRecord(logging.LogRecord):
    def getMessage(self):
        msg = self.msg
        if self.args:
            if isinstance(self.args, dict):
                msg = msg.format(**self.args)
            else:
                msg = msg.format(*self.args)
        return msg

class Logger(logging.Logger):
    def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
        rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
        if extra is not None:
            for key in extra:
                rv.__dict__[key] = extra[key]
        return rv

Then just set the logging class:

然后只需设置日志记录类:

logging.setLoggerClass(Logger)

回答by yusuf

You could do also (Python 3);

你也可以这样做(Python 3);

logging.info(f'date={date}')