Python中的条件日志记录

5

我想在一个模块中加入日志记录,但是我不想让该模块创建一个新的日志对象/文件,我希望它使用调用者的日志对象,无论这个对象是什么,但前提是他们必须传递一个。我知道我可以将所有的日志调用放在try块中,但那样很笨拙。最后,我想出了一种方法,似乎可以工作,但它看起来相当杂乱无章,我相信有更好的方法来解决这个问题。

class MyClass(object):
    def __init__(self, arg1, arg2, log=None):
        if log == None:
            class log(object):
                def error(self, msg): pass
                def warning(self, msg): pass
                def info(self, msg): pass
                def debug(self, msg): pass
            self.log = log()
        else:
            self.log = log
        self.log.debug('Starting')

有什么更好的方法来做这样的事情吗?

谢谢!


我认为这很不错。只需将您的日志类放入单例中并将其命名为NoneLog或类似名称,以减少使用它的每个类中的代码量。 - Arne
3个回答

2
大多数记录器使用工厂模式,让一些集中的资源管理哪些类(如果有的话)获取实际记录日志的记录器(而不是调用虚拟函数)。这意味着有一个集中的API、集中的控制,并且不需要按类定义记录器。
通常将传递的参数视为一件事情向另一件事情发出的信号,“你需要使用这个对象来完成你的工作”。除非MyClass是一个记录器,否则将其作为参数传递给它并没有什么意义——如果它需要一个记录器来完成它的工作,那就是糟糕的设计。

1

一个常用的模式:

import logging
LOGGER = logging.getLogger(__name__)

class MyClass(object):
    logger = LOGGER

    def do_something(self, somesuch):
        self.logger.debug("Starting %s", somesuch)

myInstance = MyClass()
if need_fancy_logging:
    myInstance.logger = logging.getLogger("FancyLogger")

myInstance.do_something("blabla")

编辑:标准的logging模块实际上已经做得很好了,包括什么都不做。

Python 2.7 (r27:82500, Sep 16 2010, 18:03:06) 
[GCC 4.5.1 20100907 (Red Hat 4.5.1-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging
>>> log = logging.getLogger('foo')
>>> log.debug('debug')
>>> log.info('info')
>>> log.error('error')
No handlers could be found for logger "foo"
>>> log.error('error')
>>> 

请注意,除了打印一次警告以指示消息已被消耗并且此特定记录器是有责任的之外,绝对不会发生任何输出。

我觉得我可能漏掉了什么或者没有表达清楚。我正在编写的类将被他人使用,而我无法控制他们的操作。如果他们设置了日志记录,我想记录消息,但如果他们没有设置日志文件,我不想转储到stdout(因为我认为它会这样做)。你的方法能够实现这一点吗? - zenzic

0

直接使用 logging 模块提供的函数,例如:

logging.debug('Starting')

并让调用者自行更改根记录器(如果他们想要的话)。


我不明白。如果他们没有传递日志对象,这怎么能工作? - zenzic
日志记录模块是标准库的一部分,不需要将自定义日志对象传递给每个导入的模块。 - Wooble

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