Python 从静态方法记录日志

Python 从静态方法记录日志,python,logging,Python,Logging,在一个几乎没有静态函数的类中,我通常这样做日志记录: class ClassA: def __init__(self): self._logger = logging.getLogger(self.__class__.__name__) def do_something(self): self._logger.info("Doing something") def do_something_else(self): se

在一个几乎没有静态函数的类中,我通常这样做日志记录:

class ClassA:

    def __init__(self):
        self._logger = logging.getLogger(self.__class__.__name__)

    def do_something(self):
        self._logger.info("Doing something")

    def do_something_else(self):
        self._logger.info("Doing something else.")
在使用静态方法的类中,我一直在这样做:

class ClassB:

    _logger = logging.getLogger("ClassB")

    @staticmethod
    def do_something():
        ClassB._logger.info("Doing something")

    @staticmethod
    def do_something_else():
        ClassB._logger.info("Doing something else")
你可以这样做,但这似乎是站不住脚的:

class ClassB:

    @staticmethod
    def do_something():
        logger = logging.getLogger("ClassB")
        logger.info("Doing something")

    @staticmethod
    def do_something_else():
        logger = logging.getLogger("ClassB")
        logger.info("Doing something else")

从静态方法记录日志有更好的模式吗?

您可以将它们改为类方法

class ClassB(object):
    _logger = logging.getLogger("ClassB")

    @classmethod
    def do_something(cls):
         cls._logger.info("Doing something")

但是请注意,当您从
ClassB
派生并调用
do\u something
时,它将得到一个不同的记录器,因为
cls
表示派生类,而不是
ClassB

,这几乎耗尽了您的选择。毕竟,静态方法只能访问三个作用域:方法作用域、类作用域和模块作用域。如果您想让记录器名称与类名匹配,那么每个类至少需要一个记录器,因此,如果您还想将它们存储在类范围内(如第二个示例所示),那么将它们存储在模块范围内是没有意义的


就我个人而言,我通常每个模块使用一个记录器。但是如果我在做单独的类记录器,我可能会使用您的模式#2,在每个类中都有一个
\u logger
变量。对我来说,这似乎是最干净的。

回答派对迟到了,但我想再补充一点

如果您有一个更复杂的记录器初始化(要登录到的init文件路径等),那么您可以通过在类之外创建logger_init来完成

def init_logger():
    logger = logging.getLogger('general_logger')
    # do other logger setup like
    # setup logger handlers,
    # set formatters,
    # set logging levels, etc
    return logger
然后,从静态类初始化记录器

 class MyClass(object):
     _logger = init_logger()

     @classmethod
     def do_something(cls):
         cls._logger.info("doing something")

祝你伐木愉快

实际上,我喜欢记录器名称将显示派生类的名称的想法。所以我想我会像你的例子那样做。谢谢你确认没有其他选择。我希望我能给出两个答案(你的和拉斯曼的),但我对你有用的回答投了更高的票。我对每个模块记录器的评分为+1;这实际上是我倾向于做的。这表明,如果在模块级创建日志实例并从文件加载配置,则应将设置为
False
,因为如果没有此设置,只有配置中特别列出的记录器将保持活动状态(除非在加载配置后导入模块)。