当我们打印一些字符时,并不是调用print
函数后就立即打印的。一般会先将字符送到缓冲区,然后再打印。这就存在一个问题,如果你想立刻看到日志,但由于缓冲区没满,不会打印。就需要采取一些手段。如每次打印后强行刷新缓冲区。
解决方案:
- sys.stdout.flush()
python的stdout是有缓冲区的,给你个例子你就知道了
import time
import sys
for i in range(5):
print i,
#sys.stdout.flush()
time.sleep(1)
这个程序本意是每隔一秒输出一个数字,但是如果把这句话sys.stdout.flush()注释的话,你就只能等到程序执行完毕,屏幕上会一次性输出0,1,2,3,4。
如果你加上sys.stdout.flush(),刷新stdout,这样就能每隔一秒输出一个数字了。
可以用在网络程序中多线程程序,多个线程后台运行,同时要能在屏幕上实时看到输出信息。
- python -u xx.py
用网上的一个程序示例来说明,python中stdout
默认需要缓存后再输出到屏幕,而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()均是向屏幕打印的语句。其实python中的print语句就是调用了sys.stdout.write(),例如在打印对象调用print obj时,事实上是调用了 sys.stdout.write(obj+'\n')。
预想的结果是:stdout1stderr1stdout2stderr2
实际的结果为:stderr1stderr2stdout1stdout2
原因是python缓存机制,虽然stderr
和stdout
默认都是指向屏幕的,但是stderr
是无缓存的,程序往stderr
输出一个字符,就会在屏幕上显示一个;而stdout
是有缓存的,只有遇到换行或者积累到一定的大小,才会显示出来。这就是为什么上面的会最先显示两个stderr
的原因!
- u参数的使用
有了上面的铺垫,就可以引出python 的- u
参数了。python命令加上- u
(unbuffered)参数后会强制其标准输出也同标准错误一样不通过缓存直接打印到屏幕。
运行结果 :stdout1stderr1stdout2stderr2
这样变成了预期的输出了。
不难看出在将python执行脚本输出到屏幕结果直接重定向到日志文件的情况下,使用- u
参数,这样将标准输出的结果不经缓存直接输出到日志文件。