2016-03-03 54 views
4

我只是偶然在試圖證明同時使用print和控制檯記錄控制檯上的消息時,以下令人驚訝的行爲:控制檯記錄器爲什麼不與打印同步?

import logging 

for i in range(1, 10): 
    print("Hello") 
logging.warning("Hello world") 

# Possible result: 
Hello 
WARNING:root:Hello world 
Hello 
Hello 
Hello 
Hello 
Hello 
Hello 
Hello 
Hello 

# Expected result: 
Hello 
Hello 
Hello 
Hello 
Hello 
Hello 
Hello 
Hello 
Hello 
WARNING:root:Hello world 

這怎麼可能?

不應該保證記錄器在返回之前在其輸出流(不管它是文件還是控制檯)上寫入數據嗎?

+0

日誌記錄包括'線程'和work side sideloop。 爲可能的輸出啓動兩個線程(主循環+日誌記錄)。 – dsgdfg

+0

你知道這是記錄在哪裏嗎? –

+1

我也在尋找這種行爲。所以我添加了一個kludge,讓每次調用print()刷新stdout,這似乎讓事情變得更好。但是在日誌調用之後執行'print()'輸出後,仍然有很多次輸出日誌。我無法相信,在Python中配置記錄器以便與print()同步沒有比較方法。 –

回答

1

這些是你的問題引發的幾個不同的問題。首先,聲明

logging.Formatter('{asctime} {name} {levelname:8s} {message}', style='{') 

沒有任何影響,因爲你實例化一個Formatter,然後扔掉的結果。您需要將格式化程序分配給Handler,並將其添加到Logger。這全部記錄在Python stdlib documentation中。

其次,在你的例如兩個不同輸出流 - print寫入sys.stdoutlogging.warning,沒有其他的配置,寫入sys.stderr。如何將這些流複用到單個控制檯上並沒有很好的定義,並取決於如何設置I/O緩衝,操作系統和其他因素。

+0

格式化程序對不起,我忘了從我的代碼中刪除它。 –