首页 > 解决方案 > 字典中的代码在没有被调用的情况下运行

问题描述

我正在创建一个日志功能,并使用字典来确定日志级别。但是,字典中的值(代码)在没有调用它的情况下运行。

def debug(level = 0, text = ''):
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    Formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s', datefmt = '%Y-%m-%d %H:%M:%S')
    
    fileLog = logging.FileHandler('test.log')
    fileLog.setLevel(logging.DEBUG)
    fileLog.setFormatter(Formatter)
    logger.addHandler(fileLog)
    streamLog = logging.StreamHandler()
    streamLog.setLevel(logging.DEBUG)
    streamLog.setFormatter(Formatter)
    logger.addHandler(streamLog)
    log = str(sys._getframe(1).f_code.co_name + "  " + text)
    logLevel = {
        0: logger.debug(log),
        1: logger.info(log),
        2: logger.warning(log),
        3: logger.error(log),
        4: logger.critical(log)
    }
    logLevel.get(level, None)

def test():
    debug(0, "MESSAGE")

我该如何解决这个问题?

标签: python

解决方案


必须在创建字典之前评估字典的值。没有办法解决这个问题。

您可以做的是将值包装在一个函数中,然后稍后调用该函数:

logLevel = {
    0: lambda: logger.debug(log),
    1: lambda: logger.info(log),
    2: lambda: logger.warning(log),
    3: lambda: logger.error(log),
    4: lambda: logger.critical(log)
}

log_f = logLevel[1]
log_f()  # Will call the "lambda: logger.info(log)" function.

这些值仍在评估中,但现在评估的是函数,而不是它包含的代码。

这也可以通过使用来实现functools.partial

from functools import partial

logLevel = {
    0: partial(logger.debug, log),
    1: partial(logger.info, log),
    2: partial(logger.warning, log),
    3: partial(logger.error, log),
    4: partial(logger.critical, log)
}

log_f = logLevel[1]
log_f()

关键是需要延迟执行,而函数包装器是实现这一目标的最简单(但不一定是唯一的选择)。


推荐阅读