为什么 xlwings 禁止记录到文件

why xlwings suppresses logging to a file

在我的 app.py 模块中,我设置了一个带有控制台和文件处理程序的记录器,如下所示:

import logging


logger = logging.getLogger('app')
logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
file_handler = logging.FileHandler('gsam_log.txt')
console_handler.setLevel(logging.INFO)
file_handler.setLevel(logging.INFO)
c_formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
f_formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')

console_handler.setFormatter(c_formatter)
file_handler.setFormatter(f_formatter)
logger.addHandler(console_handler)
logger.addHandler(file_handler)

如果我在 Python 控制台中工作并且我这样做:from app import logger 它按预期工作 - 打印到控制台和文件。我想使用这个记录器从我的 xlwings 潜艇(用 @xw.sub 装饰)记录。但出于某种原因,日志只发送到控制台而不是文件。下面是来自 test.py 模块的代码,我通过 xlwings.

将其导入为 UDF 模块
from app import logger
import xlwings as xw


@xw.sub
def test():
    logger.debug('test')
    logger.info('test')
    logger.warning('test')

我不太熟悉 xlwings 的工作原理,但由于 logging 模块的工作原理错综复杂,我建议不要在模块的全局范围内创建记录器,而是根据需要懒惰地创建它们。

在许多情况下,在全局范围内创建的日志是在之前创建的,任何代码都是运行。然后,其他一些代码会重新配置日志记录,这会导致删除现有日志并忘记其配置。这就是 disable_existing_loggers=False 参数存在于 logging.config 函数(例如 https://docs.python.org/2/library/logging.config.html#logging.config.fileConfig)的原因。

要查看是否是这种情况,我建议将您的日志定义代码移动到一个函数中,并根据需要调用它,例如:

导入日志记录

# app.py
_logger = None

def get_logger():
    global _logger
    if _logger is None:

        _logger = logging.getLogger('app')
        _logger.setLevel(logging.DEBUG)
        # ... continue to define your logger ...

    return _logger

然后在你的函数中:

from app import get_logger
import xlwings as xw

@xw.sub
def test():
    logger = get_logger()
    logger.debug('test')
    logger.info('test')
    logger.warning('test')

需要注意的是,这不是使用日志记录的 "cleanest" 方式(通常这不是必需的)但是如果问题真的是其他一些模块扰乱了日志记录配置,这可能会很困难变通。