Wget 以非常清晰的方式将速度信息打印到标准输出,其中在下载文件时显示和刷新速度,并在屏幕上滚动一个条。我想在 Python 程序中复制这种输出。这怎么可能?
我认为curses库应该能够做到这一点;这就是我想出的:-
import curses, time
class Speeder( object ):
"""Show and refresh time and download speed in a curses interface."""
t1 = 0. # start time
t = 0. # current time
tf = 0. # end time
def start(self, filename=None ):
"""Start timer"""
self.t1 = self.t = time.time()
curses.use_env(True)
curses.initscr()
self.win = curses.newwin(4, 0)
if filename is not None:
self.win.addnstr(filename, 50 )
self.win.refresh()
def update(self, rbytes):
"""Refresh speed."""
t = time.time()
td = t - self.t
self.t = t
speed = rbytes / td
self.win.addstr(0,54,str('{0:.02f} B/s'.format(speed)))
self.win.refresh()
def end(self):
"""End timer"""
self.tf = time.time()
curses.endwin()
try:
speed = Speeder()
speed.start(filename='foo.bar')
for i in xrange(10):
time.sleep(0.5)
speed.update(200)
finally:
speed.end()
问题是它占据了整个窗口,而我一次只需要一行。我宁愿不将所有命令行历史记录推回终端窗口上方。如果我错了,请纠正我,但我目前认为 curses 应用程序总是占据整个终端窗口。
因此,我查看了tty和termios模块,但找不到任何我想做的示例。
最后,我遇到了一篇博客文章,它通过简单地将一些特殊字符写入 sys.stdout 来实现。将他的代码应用于我的 Speeder 课程,我想出了这个:-
import sys
class Speeder( object ):
"""Show and refresh time and download speed."""
t1 = 0. # start time
t = 0. # current time
tf = 0. # end time
def start(self, filename=None ):
"""Start timer"""
self.t1 = self.t = time.time()
if filename is not None:
sys.stdout.write( '\r\x1b[K' + filename.ljust(50) )
sys.stdout.flush()
def update(self, rbytes):
"""Refresh speed."""
t = time.time()
td = t - self.t
self.t = t
speed = '{0} B/s'.format( rbytes / td )
sys.stdout.write( "\r\x1b[K" + speed.rjust(65) )
sys.stdout.flush()
def end(self):
"""End timer"""
self.tf = time.time()
sys.stdout.write('\n')
这有更少的代码行,我喜欢,但是我不知道发生了什么,或者如何修改它以仅更新行的一部分,类似于 curses.addstr 函数。目前,文件名被空格覆盖。我当然可以修改该类以每次从 python 构造整行,但我想了解这一点以便根据我自己的需要对其进行调整。
作者说这只能在 VT100 终端上实现。所以我想这只能在Unix终端上工作吗?很好,但是有没有任何 Unix 终端不能在上面工作?
是否有关于该主题的更好的文档,或更复杂的示例(例如更新多行、一行多行或一行中的单个字符),最好用于 Python?这似乎不是 Python 的一个特性,而是 tty,这就是为什么我想我什么都没找到。是否有手册页或我应该阅读的内容?