loggeradapter - Python: Logging TypeError: no todos los argumentos se convierten durante el formato de cadena
python logging disable_existing_loggers (4)
La respuesta de Martijn es correcta, pero si prefiere utilizar un nuevo formato de estilo con el registro, puede lograrse mediante la subclasificación del registrador.
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
Luego simplemente establece la clase de registro:
logging.setLoggerClass(Logger)
Esto es lo que estoy haciendo.
>>> 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
>>>
Mi versión de python es
$ python --version
Python 2.7.3
¿Cómo lo hago funcionar?
No puede usar el formato de estilo nuevo cuando usa el módulo de registro; use %s
lugar de {}
.
logging.info(''date=%s'', date)
El módulo de registro utiliza el operador %
estilo antiguo para formatear la cadena de registro. Ver el método de debug
para más detalles.
Si realmente desea usar el formato de cadena str.format()
, considere usar objetos personalizados que apliquen el formato ''tarde'', cuando en realidad se convierta en una cadena:
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))
Este es un enfoque que propone la documentación del módulo de logging
Python 3 , y también funciona en Python 2.
Podrías hacer también (Python 3);
logging.info(f''date={date}'')
Usted podría hacer el formato usted mismo:
logging.info(''date={}''.format(date))
Como lo señaló Martijn Pieters, esto siempre ejecutará el formato de cadena, mientras que el uso del módulo de registro causará que el formato solo se realice si el mensaje se registra realmente.