我想在函数中实现可选的记录器。类似的东西:
def foo(arg1, arg2, arg3, logger=None):
logger = logger or (lambda *x: None)
...
self.logger.debug("The connection is lost.")
我希望在记录器存在的情况下进行日志记录。否则,记录器的调试将不起作用。
基本上,实现它的简单方法是将每个调试语句嵌套在if logger
块中,但是当有许多调试语句时它似乎很乱。
答案 0 :(得分:7)
几个选项:
创建一个虚拟记录器(我最喜欢的):
logger = logger or logging.getLogger('dummy') # without configuring dummy before.
创建一个具有一级null
效果的虚拟对象:
class DummyObject(object):
def __getattr__(self, name):
return lambda *x: None
logger = logger or DummyObject()
将每个调试语句嵌套在一个块中:
if logger:
logger.debug("abc")
答案 1 :(得分:6)
自Python 2.7以来,logging
模块中包含无操作NullHandler
:
import logging
logging.getLogger('foo').addHandler(logging.NullHandler())
答案 2 :(得分:2)
那就是logging
模块的用途。 How to use,Cookbook。
如果你真的想自己动手,我会看到一些选择:
self.logger
属性。在构造对象时设置或从基类继承。每个对象都有自己的记录器,因此您可以对每个实例进行选择性记录。
使用静态方法或独立模块的记录器类。可能有默认方法什么都不做,但用户可以随时用真正的处理程序替换它们。所有类都访问相同的对象或模块。丢失粒度,但设置工作较少。
<强> Decorators 即可。在要记录的每个方法上方放置@log('message', LEVEL)
,这将在调用方法时自动调用日志。相当清洁,灵活性较差。
答案 3 :(得分:1)
我认为你想要的是日志过滤, 所以我的答案是关于如何简单地实现日志过滤。
Python的日志包已经完成了这项工作,您可以通过多种方式进行日志记录过滤。
两种基本方式是:
它们都使用日志记录的配置,因此可以轻松配置。
例如:
import logging
logging.basicConfig() # easily setup a StreamHandler output
logging.getLogger("realm1").setLevel(logging.WARNING)
logging.getLogger("realm2").setLevel(logging.INFO)
def test():
r1logger = logging.getLogger("realm1")
r2logger = logging.getLogger("realm2")
r1logger.info('r1 info') # won't print
r2logger.info('r2 info') # will print
if __name__ == '__main__':
test()
因此,除非您需要运行时动态本地更改日志记录策略, 使用默认记录器并仔细记录配置就足够了。
答案 4 :(得分:1)
默认情况下,调用 logging.getLogger
时用于构造新记录器的类是 logging.Logger
,默认情况下会将 propagate
属性设置为 True
({{3 }})。根据文档,
如果此属性 [propagate
] 的计算结果为 true,则除了附加到此记录器的任何处理程序之外,记录到此记录器的事件还将传递给更高级别(祖先)记录器的处理程序。
因此,只要记录器的父级之一具有一些重要的处理程序,@fcs 的答案就不会起作用,这很可能是这种情况,因为根记录器都是记录器的父级,并且它几乎总是具有 StreamHandler
使用 stderr
流。
以下简单修复将起作用:
import logging
null_logger = logging.getLogger('foo')
null_logger.addHandler(logging.NullHandler()) # read below for reason
null_logger.propagate = False
null_logger.error("error") # This message will still go nowhere
请注意,添加 logging.NullHandler
是必要的,因为如果日志记录未被任何处理程序处理,它将由 logging.lastResort
处理,它仍然会将此消息发送到 stderr
(行为从 Python 3.2 开始)。
答案 5 :(得分:0)
您还可以做些什么,它要短一些,然后使用NullHander设置一个真正的记录器:
logger = Mock()