2013-02-27 100 views
4

我需要根据变量的值更改日志记录级别。例如:基于变量值的Python日志记录级别?

if accel >= 10.0: 
    log_func = logging.critical # Critical for splat event 
elif accel >= 2.0: 
    log_func = logging.warning # Warning for high-G 
elif accel >= 1.0: 
    log_func = logging.info  # Info for normal 
else: 
    log_func = logging.debug # Debug otherwise 
log_func("Collision with %0.1fG impact.", accel) 

我有这个全部通过我的代码的实例。有没有更好的办法?

+0

您总是以该逻辑结束'logging.info'或'logging.debug'。因为当'accel> = 10.0'为真时,'accel> = 2.0'也是。除了第一次测试之外,你想用'elif'代替'if'。 – 2013-02-27 18:04:18

+1

谢谢!我疯狂编辑实际的代码到最小的例子。固定。 – BobC 2013-02-27 20:27:44

回答

4

是,使用Logger.log()方法来代替,并通过在一个水平不变:

import sys 

# Map accel values to log levels 
levels = (
    (10.0, logging.CRITICAL), 
    (2.0, logging.WARNING), 
    (1.0, logging.INFO), 
    (-sys.maxsize, logging.DEBUG) 
) 

logging.log(next(lev[1] for lev in levels if lev[0] <= accel), 
    "Collision with %0.1fG impact.", accel) 

你可以封装级别选择成效用函数:

def level_for_accel(accel): 
    # return next matching log level for the given accel value 
    return next(lev[1] for lev in levels if lev[0] <= accel) 

logging.log(level_for_accel(accel), "Collision with %0.1fG impact.", accel) 

日志级别实际上是整数,而CRITICALWARNING等值只是常数。有多种方法可以用一些简单的规则将一个值(例如accel)转换为匹配的日志级别,其方式比大量的if/else分支更可读。

+1

我喜欢使用logging.log()的想法,但是上面的内容增加了视觉和执行的复杂性,没有改善空间或清晰度。但是这确实表明我实际上是在对数据进行分箱,而记录只是一个结果。我想我需要一个数据分类器,以及一个将分类映射到日志级别的通用日志包装器。 – BobC 2013-02-27 20:30:18

+0

@ user1366715:'next()'调用当然可以很容易地封装在一个函数中。重点在于,您不选择日志记录便利功能,而只是选择日志*级别*。 – 2013-02-27 20:30:57

+0

这当然是正确的方向。我想避免明确地混合'水平'中的值和日志级别(在多次使用后变老),并且具有通用日志级别。也许传递一个元组(accel,(10.0,2.0,1.0,0.0))? – BobC 2013-02-27 20:38:15

2

您可以创建一个函数,它接受变量accel并返回相应的日志记录功能。然后调用它。它可能会更干净,更易于维护的代码。更不用说DRY了。

def logger(accel): 
    if accel >= 10.0: 
     return logging.critical # Critical for splat event 
    if accel >= 2.0: 
     return logging.warning # Warning for high-G 
    if accel >= 1.0: 
     return logging.info  # Info for normal 
    else: 
     return logging.debug # Debug otherwise 

然后,你可以使用它作为

logger(12)("hello world") 
+1

确实如此,但由于它是一次性代码,因此我正在寻找更高级别的模板,而不是增加函数调用的开销。 – BobC 2013-02-27 20:30:01