2013-02-27 35 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