使用 python 的
logging
模块,如果记录了错误或关键,我想返回非零,如果没有记录错误或关键,则返回零。我是否必须添加一个层来捕获它,或者这是本机功能吗?
import logging
def CheckMaxErr():
pass
logging.debug("Cat")
CheckMaxErr() #should return logging.DEBUG
logging.error("Dog")
CheckMaxErr() #should return logging.ERROR
您可以实现日志处理程序的子类,并在实例上设置标志属性(如果曾经调用过该实例)。您可以将处理程序的级别设置为
logging.ERROR
级别,以使其在这些消息上触发。
import logging
class MyHandler(logging.Handler):
def __init__(self):
super().__init__()
self.flag = False
def emit(self, record):
self.flag = True
logger = logging.getLogger(__name__)
handle = MyHandler()
handle.setLevel(logging.ERROR)
logger.addHandler(handle)
logger.debug("debug message")
print(handle.flag) # False
logger.error("ERROR")
print(handle.flag) # True
在此示例中,处理程序实际上并未对消息执行任何操作,只是在触发时设置标志。您可以添加另一个处理程序来记录到您想要的任何位置(控制台、文件等)
@Alex 提供的解决方案有一个令人沮丧的限制,那就是
CheckMaxError()
如何获取对处理程序的引用以查询所看到的最大级别。
如果您位于包含自定义处理程序的变量范围内,这当然是微不足道的,但否则就相当困难。例如,在一个多类项目中,您有
A.py
class A:
def __init__(self):
self.log = logging.Logger("MyLog")
...
def myMethodA():
...
self.log.info("some message")
...
B.py
class B:
def __init__(self):
self.log = logging.Logger("MyLog")
...
def myMethodB():
...
self.log.info("some message")
...
main.py
...
if __name__== "__main__":
log = logging.Logger("MyLog")
hdlr = MyHandler()
log.addHandler(hdlr)
...
现在,如何实现
CheckMaxError()
,使其可以从项目中的任何位置调用,即从类 A
和 B
中调用?他们没有对自定义处理程序的引用,只有 Logger
。记录器保留已注册处理程序的列表,但没有简单的方法来检索特定处理程序,并且如果没有对自定义处理程序的引用,您将无法查询最大级别。
有一个非常简单的解决方案,子类化
logging.Logger
:
MyLogger.py
class MyLogger(logging.Logger):
def __init__(self, name, level=logging.NOTSET):
logging.Logger.__init__(self, name, level)
self.maxLevel = 0
# Override _log() method to save maximum level seen
def _log(self, level, msg, *args, **kwargs):
super()._log(level, msg, *args, **kwargs)
self.maxLevel = max(level, self.maxLevel)
在
main
中记录初始化:
logging.setLoggerClass(MyLogger)
logger = logging.getLogger(name)
现在可以查询任意点的最大等级为
logger.maxLevel
。
OO 纯粹主义者会反对,认为覆盖“私有”方法
_log()
是不行的,但文档和代码都表明它是为了 logging.Logger
进行子类化。
我认为“理想”的解决方案是通过添加公共方法
Logger
来扩展logHook(logger:Logger)
,该方法在Logger
中为空,但在子类中可以重写。 logHook
将在 _log()
方法中调用,让您有机会以某种方式对每个日志条目做出反应。