我做了一个下载器:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from __future__ import print_function, division, absolute_import, unicode_literals
import os
import argparse
try:
from urllib2 import urlopen
except ImportError:
from urllib.request import urlopen
# {{ Argument parser
parser = argparse.ArgumentParser(
prog='downloader',
description='a featureful downloader'
)
parser.add_argument(
'-o',
dest='outputfile'
)
parser.add_argument(
'-r',
dest='remotefile'
)
downloader = parser.parse_args()
# }}
# {{ default local filename
if downloader.outputfile:
default_output_file = downloader.outputfile
else:
default_output_file = os.path.split(downloader.remotefile)[-1]
# }}
u = urlopen(downloader.remotefile)
meta = u.info()
file_size = int(dict(meta.items())['Content-Length'])
print("Downloading: %s Bytes: %s" % (default_output_file, file_size))
with open(default_output_file, 'wb') as f:
file_size_dl = 0
block_sz = 8192
while True:
buffer = u.read(block_sz)
if not buffer:
break
file_size_dl += len(buffer)
f.write(buffer)
status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
status = status + chr(8)*(len(status)+1)
print(status)
此脚本的示例运行将是:
python3 downloader.py -o ubuntu.iso -r http://releases.ubuntu.com/13.04/ubuntu-13.04-desktop-i386.iso
示例输出将是:
Downloading: ubuntu.iso Bytes: 832569344
8192 [0.00%]
16384 [0.00%]
24576 [0.00%]
32768 [0.00%]
40960 [0.00%]
49152 [0.01%]
57344 [0.01%]
65536 [0.01%]
73728 [0.01%]
81920 [0.01%]
90112 [0.01%]
98304 [0.01%]
106496 [0.01%]
114688 [0.01%]
122880 [0.01%]
131072 [0.02%]
139264 [0.02%]
147456 [0.02%]
155648 [0.02%]
163840 [0.02%]
请注意,随着循环的进行,输出将打印在单独的行上。我知道我可以使用\r
(回车)来做到这一点。但是我在哪里以及如何使用它时会感到困惑。
答案 0 :(得分:15)
将\r
放在打印字符串的开头或结尾处,例如'\rthis string will start at the beginning of the line'
。或'the next string will start at the beginning of the line\r'
。从概念上讲,\r
将光标移动到行的开头,然后保持正常输出字符。
您还需要告诉print不要在字符串的末尾自动添加换行符。在python3中,您可以在this之前的stackoverflow答案中使用end=""
。
或者,您可以执行import sys
和sys.stdout.write('whatever')
代替使用打印,它只会将精确字符发送到stdout,而不会使用隐式换行符。您可能还想使用sys.stdout.flush()
,如果没有它,它会将字符存储在缓冲区中而不是立即打印它们。
答案 1 :(得分:4)
为您的打印功能添加, end="\r"
。还要确保您的打印数据有足够的空间来覆盖以前打印的数据或具有相同的长度,因为只是移动到同一行不会自动清除以前的内容。
答案 2 :(得分:2)
您可以使用sys.stdout.write
:
import time
import sys
def timer(t=5):
t0 = time.time()
now = t0
while now-t0 < t:
now = time.time()
timestr = '\r%%%i\t' %(100*(now-t0)/t)
sys.stdout.write(timestr)
sys.stdout.flush()
time.sleep(0.1)