Python的logging模块使用格式化器会导致AttributeError错误。

16

我正在编写一个终端应用程序,通过传递-v选项后,可以得到详细信息。我希望在终端中可用输出,以便进行简单的测试(无论如何,在作为cron运行时,它都会被重定向到日志文件中)。

然而,当使用格式化程序时,Python logging模块不允许我写出具有相应级别的消息。(格式化程序直接从Python Logging Cookbok复制)

这种行为不仅限于Python3。在给定条件下,Python2.7也会引发相同的异常。


one.py

from sys import stdout
import logging

if __name__ == '__main__':

    level = 20

    log = logging.getLogger()
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler = logging.StreamHandler(stdout).setFormatter(formatter)
    log.addHandler(handler)
    log.setLevel(level)

    log.info("Blah")

one.py 输出

Traceback (most recent call last):
  File "/home/tlevi/PycharmProjects/untitled/main.py", line 14, in <module>
    log.info("Blah")
  File "/usr/lib/python3.4/logging/__init__.py", line 1279, in info
    self._log(INFO, msg, args, **kwargs)
  File "/usr/lib/python3.4/logging/__init__.py", line 1414, in _log
    self.handle(record)
  File "/usr/lib/python3.4/logging/__init__.py", line 1424, in handle
    self.callHandlers(record)
  File "/usr/lib/python3.4/logging/__init__.py", line 1485, in callHandlers
    if record.levelno >= hdlr.level:
AttributeError: 'NoneType' object has no attribute 'level'

two.py(运行良好)

from sys import stdout
import logging

if __name__ == '__main__':

    level = 20

    log = logging.getLogger()
    handler = logging.StreamHandler(stdout)
    log.addHandler(handler)
    log.setLevel(level)

    log.info("Blah")

two.py 输出

Blah
1个回答

28

与其

handler = logging.StreamHandler(stdout).setFormatter(formatter)

尝试:

handler = logging.StreamHandler(stdout)
handler.setFormatter(formatter)

发生的情况是,在第一种情况下,你将setFormatter()的返回值分配给handler变量,但是setFormatter()不会返回处理程序(即它返回None)。


6
这样一个流行的库没有对链式调用提供支持,这让人感到失望。 - Rikaelus
1
@Rikaelus - 这引出了一个问题:“为什么它这么受欢迎?” - barrypicker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接