Wget的打印出的速度信息以一種非常清楚的方式,其中該速度被示出和刷新而文件被下載到stdout,並在整個屏幕中條滾動。我想在Python程序中複製這種輸出。這怎麼可能?如何在linux終端上重現wget-like速度界面?
我認爲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模塊,但是我找不到任何正在做我想做的事情的例子。
最後,我碰到a blog post這可以通過寫一些特殊字符sys.stdout來做到的。運用自己的代碼,以我的調速裝置類,我想出了這個: -
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')
這有更少的代碼,這是我喜歡的,但TBH我沒有一個線索,這是怎麼回事,或者如何修改它只更新部分行,類似於curses.addstr函數。目前,文件名被空白覆蓋。我當然可以修改這個類來每次從python構建整個行,但我想了解這一點,以便根據自己的需要進行調整。
作者說,這是可能只在VT100終端。所以我想這隻會在Unix終端上工作呢?這很好,但是有沒有Unix終端,這不會工作?
是否有關於這個問題更好的文檔,或更復雜的實施例(例如,更新多條線路,多箇中的一個線路,或單個字符上的線),優選爲Python?這看起來不像Python的一個特性,但是tty,這就是爲什麼我猜測我找不到任何東西。是否有一個手冊頁或我應該閱讀的東西?
感謝您的鏈接。絕對是我很快會讀的東西。 –
謝謝,我現在開始欣賞ANSI轉義代碼,並想出瞭如何移動光標。在後面的'update'方法中替換轉義碼,用'\ 033 [15D「'讓我把光標移回15個字符。然後我可以覆蓋已經存在的內容。繁榮! –
爲您提供幫助找到最簡單解決方案的正確答案。 –