前言
sys.stdout.write() 和 print()
官方源码
"""
sys.stdout.write(string)
Write string to stream.
Returns the number of characters written (which is always equal to the length of the string).
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
"""
- sys.stdout.write()是将str写到流,原封不动,不会像print那样默认加上’\n’(默认end=’\n’)
- sys.stdout.write()只能输出一个str,而print能输出多个str,且用一个空格隔开(默认sep=’ ')
正文
在python中,执行结果都是经由sys.stdout()输出的,而stdout具有缓冲区,即不会每一次写入就输出内容,而是会在得到相应的指令后才将缓冲区的内容输出。
sys.stdout.flush()的作用就是显示地让缓冲区的内容输出。
举个例子(来自网络)
需求:输出0,1,2,3,4,每隔1秒输出一个数。
import time
for i in range(5):
print(i)
time.sleep(1)
执行结果
结果完全符合预期?!这是为什么呢?怎么跟网上的解释的用所不同呢??
网上的输出结果为等待5秒后,一次性输出01234。
经过多次实验,发现
1.Windows
无论是否使用sys.stdout.flush()来显示刷新,结果都如上所示
2.Linux
情况略有不同,同样的代码在linux下运行
结果为
嗯?!!是不是在开玩笑啊?怎么还是这么轻易就得到了预期的结果??
那么问题出在哪里呢?
多次查询后,找到了一句引起我注意的话
— 如果缓冲区的内容中新增了换行符,那么stdout就会自动将缓冲区内的内容输出!
是不是发现了什么?print()里面有个end参数,其默认值就是 ‘\n’ !
试着将end修改为其他值,比如’ ’
import time
for i in range(5):
print(i, end=' ')
time.sleep(1)
执行结果
网上说的结果出现了,即5秒后将结果一并输出!!
嗯?好像有哪里不对?
貌似我是想让它一次输出一个值!!
1)此时就轮到sys.stdout.flush()出场了
import time
import sys
for i in range(5):
print(i, end=' ')
sys.stdout.flush()
time.sleep(1)
执行结果
貌似跟上面一样??其实执行过程中是一个一个蹦出来的!
2)其实不止sys.stdout.flush()能够达到这个目的,不知你注意到了没?print()中有一个参数flush,默认flush=False
试着将其修改为True
import time
for i in range(5):
print(i, end=' ', flush=True)
time.sleep(1)
执行结果
结果跟上述一模一样(此为执行过程)!
其实,参数flush和sys.stdout.flush()作用相同。
注:以上例子均在python3中实现
总结
- 在Windows下,无论是否使用sys.stdout.flush(),其结果都是多次输出;
- 在Linux下,可以通过三种方式实现实时将缓冲区的内容输出:
1)sys.stdout.flush()
2)向缓冲区输入换行符,将print()的参数end设置为’\n’(其实默认 的end=’\n’)
3)将print()的参数flush设置为True(默认flush=False)
其实,使用默认print()时,其结果都是分别输出。
后记
在Linux下,用python(2.x)执行
import time
for i in range(5):
print i,
time.sleep(1)
执行结果为一次性输出,正如网上所说。