从子类调用父类的方法,但未在日志文件中看到

时间:2019-01-04 15:06:17

标签: python python-3.x python-logging

我想从子类中调用父类的方法,但是运行以下命令时,我在日志文件中看不到日志记录条目:

python.exe B.py

如果我在printA()代码中调用A.py方法,则会看到日志记录条目。

下面的Python代码是A.py文件:

#!/usr/bin/env python
import logging
import logging.config
import yaml

with open('logging.yaml', 'r') as f:
    config = yaml.safe_load(f.read())
    logging.config.dictConfig(config)
logger = logging.getLogger(__name__)

class A:
    def __init__(self, name, value):
        self.name = name
        self.value = value

    def printA(self):
        logger.info('Name: {}'.format(self.name))
        logger.info('Value: {}'.format(self.value))

B.py文件:

#!/usr/bin/env python
from A import *
import logging
import logging.config
import yaml


with open('logging.yaml', 'r') as f:
    config = yaml.safe_load(f.read())
    logging.config.dictConfig(config)
logger = logging.getLogger(__name__)

class B(A):
    def __init__(self, name, value):
        super(B, self).__init__(name, value + 1)      

b = B('Name', 1)
b.printA()

logging.yaml文件:

version: 1
formatters:
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
    stream: ext://sys.stdout
  debug_file_handler:
    class: logging.handlers.RotatingFileHandler
    level: DEBUG
    formatter: simple
    filename: debug.log
    maxBytes: 10485760 # 10MB
    backupCount: 20
    encoding: utf8
root:
  level: DEBUG
  handlers: [console, debug_file_handler]

实际结果是一个空的日志文件。问题是我应该对源代码进行哪些更改以使日志记录功能完整? 感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您正在配置和重新配置logging模块,并且每次调用logging.config.dictConfig()时,会将disable_existing_loggers参数保留为dictConfig()True。请参阅文档的Dictionary Schema Details section

  

disable_existing_loggers-是否要禁用任何现有记录器。此设置镜像fileConfig()中具有相同名称的参数。如果不存在,则此参数默认为True。如果incremental为True,则忽略此值。

因此,每次调用dictConfig()时,任何logging.Logger()实例都会被禁用

在使用dictConfig()创建单个logging.getLogger(__name__)对象之前,如果仅调用Logging() 一次,您的代码就可以使用。但是,当您扩展到两个模块时,您的from A import *行将导入A,执行dictConfig()并创建一个Logger(),然后控制权返回到B模块,然后再次运行dictConfig()(否则您在logger中创建的B引用在任何地方都不会使用)。

您只需要配置一次记录日志 ,最好是尽早从主入口点(使用Python运行的脚本)进行配置,并且如果您的代码已经创建了Logger()实例您想继续使用,您需要将incremental设置为True(但要理解[然后将仅应用subset of your configuration),或将disable_existing_loggers设置为False

请记住,您始终可以更新从.yaml文件加载的词典,因此您可以使用:

config['disable_existing_loggers'] = False

在将config传递给logging.config.dictConfig()之前。

我将使用if __name__ == '__main__':防护措施来确保仅在此时配置日志记录。不要在没有这种保护措施的情况下在更改全局配置的模块中运行顶级代码:

if __name__ == '__main__':
    # this module is used as a script, configure logging
    with open('logging.yaml', 'r') as f:
        config = yaml.safe_load(f.read())
    # do not disable any logger objects already created before this point
    config['disable_existing_loggers'] = False
    logging.config.dictConfig(config)