打印到同一行而不是python中的新行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3419984/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:58:05  来源:igfitidea点击:

Print to the same line and not a new line in python

pythonstdout

提问by chriscauley

Basically I want to do the opposite of what this guy did... hehe.

基本上我想做与这家伙所做的相反的事情……呵呵。

Python Script: Print new line each time to shell rather than update existing line

Python 脚本:每次向 shell 打印新行而不是更新现有行

I have a program that is telling me how far along it is.

我有一个程序告诉我它有多远。

for i in some_list:
    #do a bunch of stuff.
    print i/len(some_list)*100," percent complete"

So if len(some_list) was 50, I'd get that last line printed 50 times over. I want to print one line and keep updating that line. I know I know this is probably the lamest question you'll read all day. I just can't figure out the four words I need to put into google to get the answer.

因此,如果 len(some_list) 为 50,我会将最后一行打印 50 次。我想打印一行并不断更新该行。我知道我知道这可能是你整天阅读的最蹩脚的问题。我就是想不通我需要输入谷歌才能得到答案的四个词。

Update! I tried mvds' suggestion which SEEMED right. The new code

更新!我尝试了 mvds 的建议,这似乎是正确的。新代码

print percent_complete,"           \r",

Percent complete is just a string (I was abstracting the first time now I an trying to be literal). The result now is that it runs the program, doesn't print ANYTHING until after the program is over, and then prints "100 percent complete" on one and only one line.

完成百分比只是一个字符串(我是第一次抽象,现在我试图成为文字)。现在的结果是它运行程序,直到程序结束后才打印任何内容,然后在一行且仅一行上打印“100%完成”。

Without the carriage return (but with the comma, half of mvds' suggestion) it prints nothing until the end. And then prints:

没有回车(但有逗号,mvds 建议的一半)它直到最后什么都不打印。然后打印:

0 percent complete     2 percent complete     3 percent complete     4 percent complete    

And so on. So now the new issue is that with the comma it doesn't print until the program is finished.

等等。所以现在的新问题是,在程序完成之前,它不会打印逗号。

With the carriage return and no comma it behaves the exact same as with neither.

使用回车而不使用逗号,它的行为与两者都没有完全相同。

采纳答案by mvds

It's called the carriage return, or \r

这叫做回车,或者 \r

Use

print i/len(some_list)*100," percent complete         \r",

The comma prevents print from adding a newline. (and the spaces will keep the line clear from prior output)

逗号可防止打印添加换行符。(并且空格将使行与先前的输出保持清晰)

Also, don't forget to terminate with a print ""to get at least a finalizing newline!

另外,不要忘记以 a 终止print ""以获得至少一个最终的换行符!

回答by chryss

Try it like this:

像这样尝试:

for i in some_list:
    #do a bunch of stuff.
    print i/len(some_list)*100," percent complete",

(With a comma at the end.)

(以逗号结尾。)

回答by Tony Veijalainen

This works for me, hacked it once to see if it is possible, but never actually used in my program (GUI is so much nicer):

这对我有用,对其进行了一次黑客攻击以查看是否可行,但从未在我的程序中实际使用过(GUI 好得多):

import time
f = '%4i %%'
len_to_clear = len(f)+1
clear = '\x08'* len_to_clear
print 'Progress in percent:'+' '*(len_to_clear),
for i in range(123):
    print clear+f % (i*100//123),
    time.sleep(0.4)
raw_input('\nDone')

回答by Remi

From python 3.x you can do:

从 python 3.x 你可以做:

print('bla bla', end='')

(which can also be used in Python 2.6 or 2.7 by putting from __future__ import print_functionat the top of your script/module)

(也可以通过放在from __future__ import print_function脚本/模块的顶部在 Python 2.6 或 2.7 中使用)

Python console progressbar example:

Python 控制台进度条示例:

import time

# status generator
def range_with_status(total):
    """ iterate from 0 to total and show progress in console """
    n=0
    while n<total:
        done = '#'*(n+1)
        todo = '-'*(total-n-1)
        s = '<{0}>'.format(done+todo)
        if not todo:
            s+='\n'        
        if n>0:
            s = '\r'+s
        print(s, end='')
        yield n
        n+=1

# example for use of status generator
for i in range_with_status(10):
    time.sleep(0.1)

回答by siriusd

for Console you'll probably need

对于控制台,您可能需要

sys.stdout.flush()

to force update. I think using ,in print will block stdout from flushing and somehow it won't update

强制更新。我认为,在打印中使用会阻止标准输出刷新并且以某种方式它不会更新

回答by dlchambers

For me, what worked was a combo of Remi's and siriusd's answers:

对我来说,有效的是 Remi 和 Siriusd 的答案的组合:

from __future__ import print_function
import sys

print(str, end='\r')
sys.stdout.flush()

回答by Robert

import time
import sys


def update_pct(w_str):
    w_str = str(w_str)
    sys.stdout.write("\b" * len(w_str))
    sys.stdout.write(" " * len(w_str))
    sys.stdout.write("\b" * len(w_str))
    sys.stdout.write(w_str)
    sys.stdout.flush()

for pct in range(0, 101):
    update_pct("{n}%".format(n=str(pct)))
    time.sleep(0.1)

\bwill move the location of the cursor back one space
So we move it back all the way to the beginning of the line
We then write spaces to clear the current line - as we write spaces the cursor moves forward/right by one
So then we have to move the cursor back at the beginning of the line before we write our new data

\b将光标的位置向后
移动一个空格所以我们将它一直移回到行的开头
我们然后写空格来清除当前行 - 当我们写空格时,光标向前/向右移动一个
所以我们有在我们写入新数据之前将光标移回行首

Tested on Windows cmd using Python 2.7

使用 Python 2.7 在 Windows cmd 上测试

回答by Francisco Costa

Based on Remi answerfor Python 2.7+use this:

基于雷米的回答Python 2.7+使用这样的:

from __future__ import print_function
import time

# status generator
def range_with_status(total):
    """ iterate from 0 to total and show progress in console """
    import sys
    n = 0
    while n < total:
        done = '#' * (n + 1)
        todo = '-' * (total - n - 1)
        s = '<{0}>'.format(done + todo)
        if not todo:
            s += '\n'
        if n > 0:
            s = '\r' + s
        print(s, end='\r')
        sys.stdout.flush()
        yield n
        n += 1


# example for use of status generator
for i in range_with_status(50):
    time.sleep(0.2)

回答by LeopardShark

Nobody has mentioned that in Python 3.3+ you don't need sys.stdout.flush(). print('foobar', end='', flush=True)works.

没有人提到在 Python 3.3+ 中你不需要sys.stdout.flush(). print('foobar', end='', flush=True)作品。

回答by tamaroth

For Python 3.6+and for any listrather than just ints, as well as using the entire width of your console window and not crossing over to a new line, you could use the following:

对于Python 3.6+任何list而不仅仅是ints,以及使用控制台窗口的整个宽度而不是跨越到新行,您可以使用以下内容:

note: please be informed, that the function get_console_with()will work only on Linux based systems, and as such you have to rewrite it to work on Windows.

注意:请注意,该功能get_console_with()仅适用于基于 Linux 的系统,因此您必须重写它才能在 Windows 上运行。

import os
import time

def get_console_width():
    """Returns the width of console.

    NOTE: The below implementation works only on Linux-based operating systems.
    If you wish to use it on another OS, please make sure to modify it appropriately.
    """
    return int(os.popen('stty size', 'r').read().split()[1])


def range_with_progress(list_of_elements):
    """Iterate through list with a progress bar shown in console."""

    # Get the total number of elements of the given list.
    total = len(list_of_elements)
    # Get the width of currently used console. Subtract 2 from the value for the
    # edge characters "[" and "]"
    max_width = get_console_width() - 2
    # Start iterating over the list.
    for index, element in enumerate(list_of_elements):
        # Compute how many characters should be printed as "done". It is simply
        # a percentage of work done multiplied by the width of the console. That
        # is: if we're on element 50 out of 100, that means we're 50% done, or
        # 0.5, and we should mark half of the entire console as "done".
        done = int(index / total * max_width)
        # Whatever is left, should be printed as "unfinished"
        remaining = max_width - done
        # Print to the console.
        print(f'[{done * "#"}{remaining * "."}]', end='\r')
        # yield the element to work with it
        yield element
    # Finally, print the full line. If you wish, you can also print whitespace
    # so that the progress bar disappears once you are done. In that case do not
    # forget to add the "end" parameter to print function.
    print(f'[{max_width * "#"}]')


if __name__ == '__main__':
    list_of_elements = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
    for e in range_with_progress(list_of_elements):
        time.sleep(0.2)