【问题标题】:how to make logging.logger to behave like print如何使 logging.logger 表现得像 print
【发布时间】:2017-01-26 21:33:30
【问题描述】:

假设我得到了这个logging.logger 实例:

import logging
logger = logging.getLogger('root')
FORMAT = "[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s"
logging.basicConfig(format=FORMAT)
logger.setLevel(logging.DEBUG)

当我尝试像使用带有动态数量参数的内置打印一样使用它时,问题就来了:

>>> logger.__class__
<class 'logging.Logger'>
>>> logger.debug("hello")
[<stdin>:1 -             <module>() ] hello
>>> logger.debug("hello","world")
Traceback (most recent call last):
  File "c:\Python2711\Lib\logging\__init__.py", line 853, in emit
    msg = self.format(record)
  File "c:\Python2711\Lib\logging\__init__.py", line 726, in format
    return fmt.format(record)
  File "c:\Python2711\Lib\logging\__init__.py", line 465, in format
    record.message = record.getMessage()
  File "c:\Python2711\Lib\logging\__init__.py", line 329, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Logged from file <stdin>, line 1

如何模拟仍在使用 logging.Logger 的打印行为?

【问题讨论】:

  • 只需将参数括在括号中,例如 logger.debug(("hello","world"))
  • 安德烈:嗯,好的,我可以按照你的模式快速搜索和替换我所有的印刷品,干杯;-)

标签: python python-3.x logging


【解决方案1】:

或者,在您对logger 的调用中定义一个接受*argsjoin 的函数:

def log(*args, logtype='debug', sep=' '):
    getattr(logger, logtype)(sep.join(str(a) for a in args))

我在此处添加了logtype 以提高灵活性,但如果不需要,您可以将其删除。

【讨论】:

  • 太棒了!我已经根据您的代码添加了我的答案,谢谢 ;)
  • ..."{}".format(a) 真的只是一种丑陋而复杂的写作方式str(a)...如果你喜欢功能风格,(f(x) for x in sequence) 也只是map(f, sequence)
【解决方案2】:

基于@Jim 原始答案的包装器:

import logging
import sys

_logger = logging.getLogger('root')
FORMAT = "[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s"
logging.basicConfig(format=FORMAT)
_logger.setLevel(logging.DEBUG)


class LogWrapper():

    def __init__(self, logger):
        self.logger = logger

    def info(self, *args, sep=' '):
        self.logger.info(sep.join("{}".format(a) for a in args))

    def debug(self, *args, sep=' '):
        self.logger.debug(sep.join("{}".format(a) for a in args))

    def warning(self, *args, sep=' '):
        self.logger.warning(sep.join("{}".format(a) for a in args))

    def error(self, *args, sep=' '):
        self.logger.error(sep.join("{}".format(a) for a in args))

    def critical(self, *args, sep=' '):
        self.logger.critical(sep.join("{}".format(a) for a in args))

    def exception(self, *args, sep=' '):
        self.logger.exception(sep.join("{}".format(a) for a in args))

    def log(self, *args, sep=' '):
        self.logger.log(sep.join("{}".format(a) for a in args))

logger = LogWrapper(_logger)

【讨论】:

  • 这样,%lineno 将始终是 LogWrapper 中的那个,这可能是不需要的。
【解决方案3】:

将 sys.stdout 设置为您的日志记录流。

例如 logging.basicConfig(level=logging.INFO, stream=sys.stdout)

【讨论】:

  • 我已经用 python 3.5.1 试过了,但仍然崩溃 TypeError: not all arguments converted during string formatting
  • 如果我之前发生过这种情况,导致它的行会像:('{} {}', variable1, variable2)。当更改为'{} {}'.format(variable1, variable2) 时为我修复了它。
猜你喜欢
  • 2012-11-24
  • 2017-06-19
  • 1970-01-01
  • 2016-01-15
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-19
相关资源
最近更新 更多