Python: Logging TypeError: не все аргументы, преобразованные во время форматирования строки
Вот что я делаю
>>> 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
>>>
Моя версия python
$ python --version
Python 2.7.3
Как мне заставить работать?
Ответы
Ответ 1
Вы можете сделать форматирование самостоятельно:
logging.info('date={}'.format(date))
Как было указано Martijn Pieters, это всегда будет вести форматирование строки, в то время как использование модуля протоколирования приведет к тому, что форматирование будет выполняться только в том случае, если сообщение действительно зарегистрировано.
Ответ 2
Вы не можете использовать форматирование нового стиля при использовании модуля ведения журнала; используйте %s
вместо {}
.
logging.info('date=%s', date)
Модуль протоколирования использует старый стиль %
для форматирования строки журнала. Подробнее см. debug
.
Если вы действительно хотите использовать форматирование строк 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))
Это подход Документация модуля Python 3 logging
предлагает, и это также работает и на Python 2.
Ответ 3
Ответ 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
Затем просто установите класс ведения журнала:
logging.setLoggerClass(Logger)