最近碰到了這個問題,很頭疼。幸虧找到了這篇文章:
其實還有乙個解決方法,就是直接在模組裡面生成乙個logger物件,這樣載入模組時就只載入一次,不會出現重複呼叫函式,載入handler的現象。
用python的logging模組記錄日誌時,遇到了重覆記錄日誌的問題,第一條記錄寫一次,第二條記錄寫兩次,第三條記錄寫三次。。。很頭疼,這樣記日誌可不行。網上搜尋到了原因與解決方案:
原因:沒有移除handler
解決:在日誌記錄完之後removehandler
修改前示例**:
import logging
def log(message):
logger = logging.getlogger('testlog')
streamhandler = logging.streamhandler()
streamhandler.setlevel(logging.error)
formatter = logging.formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
streamhandler.setformatter(formatter)
logger.addhandler(streamhandler)
logger.error(message)
if __name__ == '__main__':
log('hi')
log('hi too')
log('hi three')
修改前輸出結果:
2016-07-08 09:17:29,740 - error - testlog - hi修改後示例**:2016-07-08 09:17:29,740 - error - testlog - hi too
2016-07-08 09:17:29,740 - error - testlog - hi too
2016-07-08 09:17:29,740 - error - testlog - hi three
2016-07-08 09:17:29,740 - error - testlog - hi three
2016-07-08 09:17:29,740 - error - testlog - hi three
import logging
def log(message):
logger = logging.getlogger('testlog')
streamhandler = logging.streamhandler()
streamhandler.setlevel(logging.error)
formatter = logging.formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
streamhandler.setformatter(formatter)
logger.addhandler(streamhandler)
logger.error(message)
# 新增下面一句,在記錄日誌之後移除控制代碼
logger.removehandler(streamhandler)
if __name__ == '__main__':
log('hi')
log('hi too')
log('hi three')
修改後輸出結果:
2016-07-08 09:32:28,206 - error - testlog - higoogle之後,大概搞明白了,就是你第二次呼叫log的時候,根據getlogger(name)裡的name獲取同乙個logger,而這個logger裡已經有了第一次你新增的handler,第二次呼叫又新增了乙個handler,所以,這個logger裡有了兩個同樣的handler,以此類推,呼叫幾次就會有幾個handler。。2016-07-08 09:32:28,206 - error - testlog - hi too
2016-07-08 09:32:28,206 - error - testlog - hi three
所以這裡有以下幾個解決辦法:
每次建立不同name的logger,每次都是新logger,不會有新增多個handler的問題。(ps:這個辦法太笨,不過我之前就是這麼幹的。。)
像上面一樣每次記錄完日誌之後,呼叫removehandler()把這個logger裡的handler移除掉。
在log方法裡做判斷,如果這個logger已有handler,則不再新增handler。
與方法2一樣,不過把用pop把logger的handler列表中的handler移除。
下面是方法3與方法4的**示例:
方法3:
import logging
def log(message):
logger = logging.getlogger('testlog')
# 這裡進行判斷,如果logger.handlers列表為空,則新增,否則,直接去寫日誌
if not logger.handlers:
streamhandler = logging.streamhandler()
streamhandler.setlevel(logging.error)
formatter = logging.formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
streamhandler.setformatter(formatter)
logger.addhandler(streamhandler)
logger.error(message)
if __name__ == '__main__':
log('hi')
log('hi too')
log('hi three')
方法4:
import logging
def log(message):
logger = logging.getlogger('testlog')
streamhandler = logging.streamhandler()
streamhandler.setlevel(logging.error)
formatter = logging.formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
streamhandler.setformatter(formatter)
logger.addhandler(streamhandler)
logger.error(message)
# 用pop方法把logger.handlers列表中的handler移除,注意如果你add了多個handler,這裡需多次pop,或者可以直接為handlers列表賦空值
logger.handlers.pop()
# logger.handler =
if __name__ == '__main__':
log('hi')
log('hi too')
log('hi three')
自定義函式 Excel之自定義函式
在excel中,當系統函式不能滿足我們的需求時候,我們可以使用vba自定義函式,如抓取網頁資料,翻譯詞彙,手機號歸屬地查詢等。下面將介紹2個自定義函式,idymd函式 身份證年月日性別 通過身份證號,返回性別,出生年月日。語法 idymd id 引數 id,身份證號,預設身份證長度18位。vba 如...
awk中自定義函式
awk中自定義函式 定義和呼叫使用者自己的函式是幾乎每個高階語言都具有的功能,awk也不例外,但原始的awk並不提供函式功能,只有在nawk或較新的awk版本中才可以增加函式。函式的使用包含兩部分 函式的定義與函式呼叫。其中函式定義又包括要執行的 函式本身 和從主程式 傳遞到該函式的臨時呼叫。awk...
sql server中自定義函式
create function getzhye nm varchar 300 returns float as begin declare membername float set membername 0 select membername 欄位1 from 表a where 欄位2 nm if ...