Python中的条件日志记录

6 投票
3 回答
4904 浏览
提问于 2025-04-16 23:43

我想在一个模块里加入日志功能,但我不想让这个模块自己创建一个新的日志对象或文件。我希望它能使用调用这个模块的地方的日志对象,不管那个对象是什么,只要他们传递了一个过来。我知道我可以把所有的日志调用放在一个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')

有没有更好的方法来做到这一点呢?

谢谢!

3 个回答

0

直接使用logging模块提供的函数,也就是说:

logging.debug('Starting')

如果调用者想要的话,可以自己去修改根日志记录器。

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')
>>> 

请注意,除了会打印一次警告,表示这个消息被处理了,并且这个特定的记录器有问题,其他绝对不会有任何输出。

2

大多数日志记录器使用工厂模式,这样可以让一个集中管理的资源来控制哪些类(如果有的话)可以获得真正的日志记录器,而不是调用一些无用的函数。简单来说,这样就有了一个统一的接口和控制方式,不再需要在每个类里单独定义日志记录器。

通常,把传递的参数看作是一个东西对另一个东西的信号是个好主意,意思是“你需要用这个对象来完成你的工作。”除非MyClass本身就是一个日志记录器,否则把它当作参数传递是没有意义的——如果它需要一个日志记录器来完成工作,那就是设计得不太好。

撰写回答