如何在Python中编写下载进度指示器?

59 投票
10 回答
32713 浏览
提问于 2025-04-11 09:18

我正在写一个小程序,用来通过http下载文件(就像在这里描述的那样)。

我还想加一个小的下载进度指示器,显示下载的百分比。

这是我想到的:

    sys.stdout.write(rem_file + "...")    
    urllib.urlretrieve(rem_file, loc_file, reporthook=dlProgress)

    def dlProgress(count, blockSize, totalSize):
      percent = int(count*blockSize*100/totalSize)
      sys.stdout.write("%2d%%" % percent)
      sys.stdout.write("\b\b\b")
      sys.stdout.flush()

输出:MyFileName... 9%

还有其他的想法或者建议吗?

有一点让我有点烦的是,终端中百分比的第一个数字旁边的光标在闪烁。有没有办法防止这个?有没有办法隐藏光标?

编辑:

这里有一个更好的方法,使用一个全局变量来存储文件名,并且用'\r'代码:

    global rem_file # global variable to be used in dlProgress

    urllib.urlretrieve(rem_file, loc_file, reporthook=dlProgress)

    def dlProgress(count, blockSize, totalSize):
      percent = int(count*blockSize*100/totalSize)
      sys.stdout.write("\r" + rem_file + "...%d%%" % percent)
      sys.stdout.flush()

输出:MyFileName...9%

而且光标现在出现在行的末尾。好多了。

10 个回答

7

这段话的意思是,作者想分享他用来让某个功能正常工作的代码。接下来就是那段代码:

from urllib import urlretrieve
from progressbar import ProgressBar, Percentage, Bar

url = "http://......."
fileName = "file"
pbar = ProgressBar(widgets=[Percentage(), Bar()])
urlretrieve(url, fileName, reporthook=dlProgress)

def dlProgress(count, blockSize, totalSize):
    pbar.update( int(count * blockSize * 100 / totalSize) )
15

你也可以试试:

sys.stdout.write("\r%2d%%" % percent)
sys.stdout.flush()

在你的字符串开头使用一个换行符,而不是多个退格键。这样你的光标还是会闪烁,但它会在百分号后面闪烁,而不是在第一个数字下面。而且用一个控制字符代替三个,可能会减少闪烁的情况。

18

这里有一个适用于Python的文本进度条库,地址是 http://pypi.python.org/pypi/progressbar/2.2,你可能会觉得很有用:

这个库提供了一种文本模式的进度条。通常用来显示一个长时间运行的操作的进度,让你能直观地看到处理正在进行中。

ProgressBar类负责管理进度,进度条的显示格式由多个小部件(widgets)组成。小部件是根据进度状态可能会有不同显示效果的对象。小部件有三种类型:- 字符串类型的小部件,它总是会显示自己;- ProgressBarWidget类型的小部件,它每次调用更新方法时可能会返回不同的值;- ProgressBarWidgetHFill类型的小部件,和ProgressBarWidget类似,但它会扩展以填满行的剩余宽度。

这个进度条模块非常容易使用,但功能强大。而且在可用的情况下,它会自动支持像自适应大小这样的特性。

撰写回答