如何使用print或sys.stdout.write执行多行刷新
原因:
根据文章内容,如果想要在屏幕上执行多行刷新操作,需要使用底层的操作系统库。在Linux或OSX上,通常使用curses库或由terminfo/termcap数据库跟踪的底层终端控制码。而在Windows上,可以使用win32控制台API。
解决方法:
在文章中已经提到了一些解决方法,如果不介意限制在一个操作系统上或者愿意在Windows上安装第三方库,可以使用已经提到的多种选项。但是,如果需要一个跨平台的解决方案,可以直接使用asciimatics库进行安装。这个库提供了一个统一的API,可以在Linux、OSX和Windows上使用。
对于进度条,可以使用asciimatics库中的BarChart对象,具体示例可以参考文章中提到的链接和代码。
文章最后提到,作者对于Python没有提供一个类似的跨平台控制台操作的库感到惊讶,特别是考虑到Tkinter这样的存在。作者并不清楚完整的历史,但据他所知,没有人愿意编写和支持一个兼容Windows的API,所以官方推荐使用已经提到的各种粘合代码选项。
如何使用print或sys.stdout.write执行多行刷新的方法
问题的出现原因:
问题的出现是因为在打印多行文本时,如果不进行刷新操作,每次打印的内容会依次显示在屏幕上,造成内容的堆叠,难以阅读。
解决方法:
解决方法是通过在打印新内容之前,先将屏幕上已有的内容清除掉,然后重新打印新的内容。可以使用以下代码实现多行刷新:
import sys import time from collections import deque queue = deque([], 3) for t in range(20): time.sleep(0.5) s = "update %d" % t for _ in range(len(queue)): sys.stdout.write("\x1b[1A\x1b[2K") # move up cursor and delete whole line queue.append(s) for i in range(len(queue)): sys.stdout.write(queue[i] + "\n") # reprint the lines
这段代码中,通过使用"\x1b[1A\x1b[2K"来控制光标的位置,将光标移动到上一行并清除整行内容,实现了多行刷新的效果。
另外,如果希望在完成打印后清除屏幕上的所有内容,可以使用以下代码:
import sys import time from collections import deque queue = deque([], 3) t = 0 while True: time.sleep(0.5) if t <= 20: s = "update %d" % t t += 1 else: s = None for _ in range(len(queue)): sys.stdout.write("\x1b[1A\x1b[2K") # move up cursor and delete whole line if s != None: queue.append(s) else: queue.popleft() if len(queue) == 0: break for i in range(len(queue)): sys.stdout.write(queue[i] + "\n") # reprint the lines
这段代码中,在打印新内容之前,先清除屏幕上已有的所有内容,然后重新打印新的内容,实现了多行刷新并清除屏幕的效果。
以上就是使用print或sys.stdout.write执行多行刷新的方法。通过控制光标的位置和清除内容,可以实现在命令行中打印多行文本并进行刷新的效果。
在Unix系统上,可以使用curses模块来实现多行刷新。
在Windows系统上,有几种选择:
1. PDCurses: http://www.lfd.uci.edu/~gohlke/pythonlibs/
2. 上述链接中推荐使用Console模块
3. http://newcenturycomputers.net/projects/wconio.html
4. http://docs.activestate.com/activepython/2.6/pywin32/win32console.html
以下是一个使用curses模块的简单示例(我是一个完全不懂curses的新手):
import curses import time def report_progress(filename, progress): """progress: 0-10""" stdscr.addstr(0, 0, "Moving file: {0}".format(filename)) stdscr.addstr(1, 0, "Total progress: [{1:10}] {0}%".format(progress * 10, "#" * progress)) stdscr.refresh() if __name__ == "__main__": stdscr = curses.initscr() curses.noecho() curses.cbreak() try: for i in range(10): report_progress("file_{0}.txt".format(i), i+1) time.sleep(0.5) finally: curses.echo() curses.nocbreak() curses.endwin()
感谢,我已经在答案中添加了链接。API和Unix的curses模块一样吗?
实际上,有一个模块可以实现你想要的功能:progressbar(code.google.com/p/python-progressbar/)
但是,如何将状态行显示在屏幕底部而不是顶部(在上一行的下一行)?我想要的效果就像在一个管道中使用多个pv --name命令一样。