在python中创建模块范围的记录器是否很好?

时间:2010-08-17 12:51:24

标签: python logging coding-style import

编写python时,我经常使用日志记录模块。

在经历了一些不愉快的经历并阅读this one等文章后,我会尽可能地阻止导入时执行代码。

但是,为了简单起见,我倾向于将我的日志记录对象放在模块文件的开头:

# -*- coding: utf-8 -*-
import logging
logger = logging.getLogger('product.plugin.foo.bar')

这样,我的记录器可以全局访问,我可以在任何地方写“logger.error()”。另一种方法是在全班创建它:

class Bar(object):
    logger = logging.getLogger('product.plugin.foo.bar')

但是,现在我必须每次都输入类名。为了防止输入类名,我很想使用“self”代替静态方法。

    def my_method(self):
        Bar.logger.error('foo')

    def my_method_2(self):
        self.logger.error('foo') # ok...

    @staticmethod
    def my_method_2():
        self.logger.error('foo') # boom!

所以,首先,看起来在模块范围内创建记录器对象似乎是正确的事情 - 仍然感觉就像我这样做时最终会导致与导入相关的麻烦......

3 个答案:

答案 0 :(得分:7)

没关系。我甚至使用相同的变量名logger。任何日志记录都比没有日志记录更好,但我发现公开记录器变量,保持模块隐藏,因此您的代码只引用记录器,因此您指定的命名空间是很好的做法模块。

如果以后需要优化模块中代码的命名空间,可以在这些类中使用self.logger,或者在必要时隐藏全局记录器。

Update0

__all__ = [anything but logger]
import logging
logger = logging.getLogger("why.is.this.method.still.java.camel.case")
del logging

注意下面的S.Lott的贡献。另请注意,通常您不需要from x import *

答案 1 :(得分:1)

该死的 - 我在发布这个问题之后第二次意识到,我的“替代品”实际上没有任何不同:记录器也是在导入时创建的;)

尽管如此,我对你对处理这个问题的最佳方法的看法很感兴趣。第一种解决方案的另一个优点:我们在某些情况下必须使用try / except块中的import语句检查模块的可用性。通过在文件开头创建记录器,您可以使用它来记录此类事件。

答案 2 :(得分:0)

我会在模块的开头创建logger对象,如果合适,我甚至可能会在子模块中使用它。

无论如何,我仍然可以在一个大类中创建一个额外的日志记录对象,如果我认为这是一个好主意,那么使用日志记录很多 - 例如,当我认为分别为日志记录详细程序或日志记录处理程序配置时可能会有用这个重要的类(例如,用于排序进程或数据库查询的类可能就是这种情况)。

您不必担心您的日志记录对象可以在模块外部访问。实际上,Python根本不支持私有成员。我认为Guido van Rossum曾经写过“我们都是大人,不是吗?”。