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

后端 未结 4 1204
独厮守ぢ
独厮守ぢ 2020-12-14 14:55

Here is what I am doing

>>> import logging
>>> logging.getLogger().setLevel(logging.INFO)
>>> from datetime import date
>>&g         


        
相关标签:
4条回答
  • 2020-12-14 15:20

    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.

    0 讨论(0)
  • 2020-12-14 15:22

    You could do also (Python 3);

    logging.info(f'date={date}')
    
    0 讨论(0)
  • 2020-12-14 15:23

    Martijn's answer is correct, but if you prefer to use new style formatting with logging, it can be accomplished by subclassing 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)
    
    0 讨论(0)
  • 2020-12-14 15:26

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

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

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

    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:

    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 logging module documentation proposes, and it happens to work on Python 2 too.

    0 讨论(0)
提交回复
热议问题