【问题标题】:Have Parent Class Use Child Class Logger Name让父类使用子类记录器名称
【发布时间】:2015-11-20 21:26:03
【问题描述】:

我正在尝试设置一些日志记录,但遇到了问题。每当子类使用父类函数时,都会使用父类函数记录器名称而不是子类的记录器名称。

假设我有以下两个类:

父类:

import logging
logger = logging.getLogger('ParentClass')

class ParentClass:
    def __init___(self):
        logger.info('This is inside ParentClass')

儿童班:

import logging
logger = logging.getLogger('ChildClass')

class ChildClass(ParentClass):
    def foo(self):
        logger.info('This is inside ChildClass')

然后我运行以下脚本:

import logging
import ParentClass
import ChildClass

# Pretend I set up logging to "example.log"
foo1 = ParentClass.ParentClass()
foo2 = ChildClass.ChildClass()
foo2.foo()

我的日志文件最终看起来像:

INFO:ParentClass:This is inside ParentClass  #(<-- this comes from foo1 init)
INFO:ParentClass:This is inside ParentClass  #(<-- this comes from foo2 init)
INFO:ChildClass:This is inside ChildClass    #(<-- this comes from foo2 foo)

我正在寻找的是对 ChildClass 的 __init__ 调用,以便像这样在 ChildClass 记录器下登录:

INFO:ParentClass:This is inside ParentClass  #(<-- this comes from foo1 init)
INFO:ChildClass:This is inside ParentClass   #(<-- this comes from foo2 init)
INFO:ChildClass:This is inside ChildClass    #(<-- this comes from foo2 foo)

在不将我要使用的记录器的名称传递给 ParentClass 的情况下,是否可以这样做?

【问题讨论】:

  • 所以我必须在子类中设置_init_,然后像这样显式调用它? 编辑这种方法不起作用,我仍然在日志文件中得到相同的输出

标签: python python-3.x


【解决方案1】:

您的每个类都在为自己的代码使用自己的记录器,因为您通过两个模块中的每个模块中的全局变量访问记录器。如果您希望记录器绑定到类而不是模块,请尝试将其设为类变量,并通过self 访问它:

class ParentClass:
    logger = logging.getLogger('ParentClass') # class variable
    def __init___(self):
        self.logger.info('This is inside ParentClass')

class ChildClass(ParentClass):
    logger = logging.getLogger('ChildClass') # override parent class variable
    def foo(self):
        self.logger.info('This is inside ChildClass')

【讨论】:

  • 另外,我也感谢您解释答案!
【解决方案2】:

基于sureshvv 的帖子,我发现将它放在我父类的__init__ 方法中很有帮助:

self.log = logging.getLogger(self.__class__.__name__)

然后,子类可以使用self.log 进行日志记录,并且日志格式中的%(name)s 标记正确显示子类名称,而不是父类名称(如果您将__name__ 传递给@,则会发生这种情况987654326@.)

【讨论】:

  • 这是更好的方法,减少了一些样板代码。
【解决方案3】:

您需要将logger 设为类的属性。按照现在的情况,ParentClass 只能调用其模块中定义的记录器:它无法访问ChildClass 中的记录器(除非 ParentClass 模块导入 ChildClass 并显式调用 ChildClass.logger )。

相反,对 ParentClass 模块执行此操作:

import logging

class ParentClass:
    logger = logging.getLogger('ParentClass')

    def __init___(self):
        self.logger.info('This is inside ParentClass')

这对于 ChildClass:

import logging
import ParentClass    # I assume you do this, too

class ChildClass(ParentClass):
    logger = logging.getLogger('ChildClass')

    def foo(self):
        self.logger.info('This is inside ChildClass')

【讨论】:

    【解决方案4】:

    你可以:

    use self.__class__ as argument to getLogger().
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      • 1970-01-01
      • 2014-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多