【问题标题】:How to use \r to print on same line? [duplicate]如何使用 \r 在同一行打印? [复制]
【发布时间】:2013-06-27 19:18:57
【问题描述】:

我做了一个下载器:

#!/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 (回车) 来做到这一点。但我对在哪里以及如何使用它感到困惑。

【问题讨论】:

标签: python python-3.x stdout carriage-return


【解决方案1】:

\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 syssys.stdout.write('whatever') 而不是使用打印,这只会将确切的字符发送到标准输出而没有隐式换行符。您可能还想使用sys.stdout.flush(),没有它它会将字符存储在缓冲区中,而不是立即打印它们。

【讨论】:

    【解决方案2】:

    为您的打印功能添加, end="\r"。还要确保您的打印数据有足够的空间来覆盖以前的打印数据或具有相同的长度,因为仅移动到同一行不会自动清除以前的内容。

    【讨论】:

    • 使用'end'的好主意,但我更喜欢在打印我的值之前打印'\r',而不是之后。这样,打印的任何其他内容(例如回溯)都不会覆盖最后打印的值。
    【解决方案3】:

    你可以使用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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 2021-01-23
      • 1970-01-01
      • 2022-10-23
      • 1970-01-01
      相关资源
      最近更新 更多