转载自: 【解决】为何python程序的输出重定向到文件中会有延迟?
有时候,我们会写这样的命令行,让python结果重定向输出到某个日志文件中:
$ python xxx.py args1 >> out/xxx.log
$ python xxx.py args1 | tee -a out/xxx.log
上面那条命令的含义就是,将xxx.py这个python文件中print()原本输出到console的内容重定向到"out/xxx.log"文件中。(“>>”是追加,“>”是直接写入,即会发生覆盖);
下面那条也差不多,使用了tee命令,在保证xxx.py文件运行时将print内容输出到控制台的同时,还把这些内容保存在"out/xxx.log"文件中。
但有的时候会发生比较蛋疼的情况,那就是可能要间隔很久,你才会看到你的"out/xxx.log"中有内容;或者控制台才有内容显示。这是为啥呢?
这是因为在python中,重定向和输出到控制台的内容会先被存在缓冲区中暂存,当它遇到换行符“\n”,或者缓存区的数据积累到一定的量的时候,就会将内容写到重定向的文件或者控制台中。
那么如果我要即时写入文件,不想要延迟怎么办?
1. python的print()函数有个参数叫"flush",将它设为True,程序运行到该条输出内容时就会将缓存区的内容写出一次。即
print("HERE!!!", flush=True)
2. 命令行运行py文件的时候,加上一个命令行参数"-u"。即
python -u xxx.py args1 >> out/xxx.log
- 你在哪里想让缓存区的内容输出,就在哪里加上这句话:
sys.stdout.flush()
每当程序运行到这句话,就将缓存中的内容输出到控制台,或者重定向的文件
还有一个想提一句的小问题——既然python的print()内容都是先输出到缓存区的,那为什么直接运行含有print()函数的python程序,print()的内容都是即时输出到控制台,没有延迟呢?
那是因为,print()函数有个指定关键字参数,即我们看到的print(),其实是print(end="\n"),所以每次输出后会自动换行。而python的stdout默认看到换行符就输出,所以print()函数的内容总是即时输出到控制台的。当然,当你把它重定向到文件中的时候,就不是这样咯。