sys.stdout.write实现Python控制台实时刷新打印

Catalogue
  1. 1. 前言
    1. 1.1. 我们先来看看Print方法打印的效果
      1. 1.1.1. 输出结果
    2. 1.2. help查看
      1. 1.2.1. 输出结果
    3. 1.3. 清屏操作
  2. 2. 解决办法
    1. 2.1. 方法1
    2. 2.2. 方法2
  3. 3. 进度条实现
    1. 3.1. 进度条的特点
    2. 3.2. 实现
      1. 3.2.1. 输出效果

前言

我们先来看看Print方法打印的效果

from datetime import datetime as dt
import sys
import time

for i in range(5):
    print(dt.now())
    time.sleep(1)

输出结果

C:\Users\Administrator\PycharmProjects\untitled\venv\Scripts\python.exe C:/Users/Administrator/PycharmProjects/untitled/test.py
2018-08-06 16:46:46.636256
2018-08-06 16:46:47.636313
2018-08-06 16:46:48.636370
2018-08-06 16:46:49.636427
2018-08-06 16:46:50.637484

Process finished with exit code 0

可以看到,用print打印出来自动换行且不会清除上一个结果

help查看

help(print)

输出结果

print(...)
    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.
可以看到end=“\n”表示了print自带换行

如果我想要在一行中打印一串信息,并且在下一次执行的时候删除这一行再重新打印(效果类似如此),该如何做呢?尝试清屏可不可以?

清屏操作

清屏试一试,查阅别的博客的方法有如下代码:

import os

os.system('cls')

但这是在命令行里使用的,用在编译器里不行。

解决办法

这时候就要用到sys.stdout.write了

方法1

from datetime import datetime as dt
import sys
import time


while True:
    a = dt.now()
    sys.stdout.write("\r{0}".format(a))
    sys.stdout.flush()
    time.sleep(1)

方法2

from datetime import datetime as dt
import sys
import time


for i in range(20):
    a = dt.now()
    sys.stdout.write("\r{0}".format(a))
    sys.stdout.flush()
    sys.stdout.write('\033[4A')
    time.sleep(1)

其关键就在于使用’\r’这个转义字符(回到行首), sys.stdout.write首先打印这一行后不带任何结尾(前文已经说过print打印结尾带end=”\n”,表示自带换行,换行了就不能在对已经打印的这一行进行更改编辑),使用了转移字符”\r”使得光标回到行首,再把缓冲区显示出来,就得到了我们所需要的效果。

C:\Users\Administrator\PycharmProjects\untitled\venv\Scripts\python.exe C:/Users/Administrator/PycharmProjects/untitled/test.py
2018-08-06 18:26:21.264878

Run只会显示这一个,并且一秒钟更新一次。

进度条实现

进度条的特点

  • 有标刻度显示所占总进度比例

  • 有百分比显示所占比例

实现

import time,sys

for i in range(100):
    percent = i / 100
    sys.stdout.write("\r{0}{1}".format("|"*i , '%.2f%%' % (percent * 100)))
    sys.stdout.flush()
    time.sleep(1)

输出效果

|||||||||||||||||||||||||||||||||33.00%