??當(dāng)我們打印一些字符時(shí)井辜,并不是調(diào)用print
函數(shù)后就立即打印的。一般會(huì)先將字符送到緩沖區(qū)管闷,然后再打印粥脚。這就存在一個(gè)問(wèn)題,如果你想立刻看到日志包个,但由于緩沖區(qū)沒(méi)滿刷允,不會(huì)打印。就需要采取一些手段。如每次打印后強(qiáng)行刷新緩沖區(qū)树灶。
解決方案:
- sys.stdout.flush()
python的stdout是有緩沖區(qū)的搀菩,給你個(gè)例子你就知道了
import time
import sys
for i in range(5):
print i,
#sys.stdout.flush()
time.sleep(1)
這個(gè)程序本意是每隔一秒輸出一個(gè)數(shù)字,但是如果把這句話sys.stdout.flush()注釋的話破托,你就只能等到程序執(zhí)行完畢肪跋,屏幕上會(huì)一次性輸出0,1土砂,2州既,3,4萝映。
如果你加上sys.stdout.flush()吴叶,刷新stdout,這樣就能每隔一秒輸出一個(gè)數(shù)字了序臂。
可以用在網(wǎng)絡(luò)程序中多線程程序蚌卤,多個(gè)線程后臺(tái)運(yùn)行,同時(shí)要能在屏幕上實(shí)時(shí)看到輸出信息奥秆。
- python -u xx.py
用網(wǎng)上的一個(gè)程序示例來(lái)說(shuō)明逊彭,python中stdout
默認(rèn)需要緩存后再輸出到屏幕,而stderr
則直接打印到屏幕
import sys
sys.stdout.write("stdout1")
sys.stderr.write("stderr1")
sys.stdout.write("stdout2")
sys.stderr.write("stderr2")
其中sys.stdout.write()和sys.stderr.write()均是向屏幕打印的語(yǔ)句构订。其實(shí)python中的print語(yǔ)句就是調(diào)用了sys.stdout.write()侮叮,例如在打印對(duì)象調(diào)用print obj時(shí),事實(shí)上是調(diào)用了 sys.stdout.write(obj+'\n')悼瘾。
預(yù)想的結(jié)果是:stdout1stderr1stdout2stderr2
實(shí)際的結(jié)果為:stderr1stderr2stdout1stdout2
原因是python緩存機(jī)制囊榜,雖然stderr
和stdout
默認(rèn)都是指向屏幕的,但是stderr
是無(wú)緩存的亥宿,程序往stderr
輸出一個(gè)字符卸勺,就會(huì)在屏幕上顯示一個(gè);而stdout
是有緩存的烫扼,只有遇到換行或者積累到一定的大小曙求,才會(huì)顯示出來(lái)。這就是為什么上面的會(huì)最先顯示兩個(gè)stderr
的原因材蛛!
- u參數(shù)的使用
有了上面的鋪墊圆到,就可以引出python 的- u
參數(shù)了怎抛。python命令加上- u
(unbuffered)參數(shù)后會(huì)強(qiáng)制其標(biāo)準(zhǔn)輸出也同標(biāo)準(zhǔn)錯(cuò)誤一樣不通過(guò)緩存直接打印到屏幕卑吭。
運(yùn)行結(jié)果 :stdout1stderr1stdout2stderr2
這樣變成了預(yù)期的輸出了。
不難看出在將python執(zhí)行腳本輸出到屏幕結(jié)果直接重定向到日志文件的情況下马绝,使用- u
參數(shù)豆赏,這樣將標(biāo)準(zhǔn)輸出的結(jié)果不經(jīng)緩存直接輸出到日志文件。