Python -u 和 sys.stdout.flush()

  当我们打印一些字符时,并不是调用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缓存机制,虽然stderrstdout默认都是指向屏幕的,但是stderr是无缓存的,程序往stderr输出一个字符,就会在屏幕上显示一个;而stdout是有缓存的,只有遇到换行或者积累到一定的大小,才会显示出来。这就是为什么上面的会最先显示两个stderr的原因!

- u参数的使用
有了上面的铺垫,就可以引出python 的- u参数了。python命令加上- u(unbuffered)参数后会强制其标准输出也同标准错误一样不通过缓存直接打印到屏幕。

运行结果 :stdout1stderr1stdout2stderr2
这样变成了预期的输出了。

不难看出在将python执行脚本输出到屏幕结果直接重定向到日志文件的情况下,使用- u参数,这样将标准输出的结果不经缓存直接输出到日志文件。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容