【问题标题】:Print to the same line and not a new line?打印到同一行而不是新行?
【发布时间】:2011-03-26 02:25:26
【问题描述】:

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

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

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

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

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

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

print percent_complete,"           \r",

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

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

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

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

使用回车且不带逗号时,其行为与不带逗号完全相同。

【问题讨论】:

  • 您可能还想检查sys.stdout.isatty(),这样您就不会在不在终端中运行时吐出这些东西。
  • 我正在从终端运行它......不过想法很好。我确定我会在某个时候需要它。
  • 背景是,顺便说一句,在几种语言中,\n(我们现在省略)用作刷新到标准输出的隐式信号。否则很多人会感到困惑。

标签: python stdout


【解决方案1】:

这叫做回车,或者\r

使用

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

逗号阻止 print 添加换行符。 (并且空格将使行从先前的输出中保持清晰)

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

【讨论】:

  • 只要确保您始终在该行打印相同数量的数据(或比任何以前的打印都多),否则最后会出现杂乱无章的情况。
  • 如此接近...我会用这个结果更新问题。
  • @dustynachos:嘿,忘了那个皱纹了。请参阅 Python 输出缓冲问题:stackoverflow.com/questions/107705/python-output-buffering
  • @dustynachos: (或者在每次打印调用后只使用 sys.stdout.flush() ,如果您不关心程序其余部分的输出缓冲,这实际上可能会更好)跨度>
  • 这对我不起作用。我实际上已经尝试了很多次,但它从来没有为我工作过。我在 Mac 上使用 iterm2,但我大部分时间都通过 ssh 连接到 linux 服务器。我从来没有找到真正有效的方法。
【解决方案2】:

对我来说,Remi 和 Siriusd 的答案组合起来奏效了:

from __future__ import print_function
import sys

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

【讨论】:

  • 过时了。从 Python 3.8.5 开始对我来说只有这样的工作:print("some string", end='\r')
  • 它在调试运行中对我有用,但在没有调试器的正常运行中不起作用,很奇怪..因为它不会刷新但它应该。
  • 只添加 end='\r' 就足够了:),谢谢!
【解决方案3】:

从 python 3.x 你可以这样做:

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

(也可以在 Python 2.6 或 2.7 中使用,方法是将 from __future__ import print_function 放在脚本/模块的顶部)

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)

【讨论】:

  • \r 似乎也添加了一个新行
  • 这去掉了换行符,但不允许覆盖,我认为这是作者想要的。
  • @bgenchel 与 '\r' 一起使用(如代码示例中所示)它完全符合 OP 的要求
【解决方案4】:

在 Python 3.3+ 中,您不需要 sys.stdout.flush()print(string, end='', flush=True) 有效。

所以

print('foo', end='')
print('\rbar', end='', flush=True)

将用“bar”覆盖“foo”。

【讨论】:

  • 只要打印的文本以"\r"结尾,它就可以工作。
【解决方案5】:

对于控制台,您可能需要

sys.stdout.flush()

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

【讨论】:

  • Terminator 仅在对我使用 print("...", end='\r') 时每 30 秒刷新一次,除非我在 print 语句之后立即运行此命令。谢谢
【解决方案6】:

游戏迟到了 - 但由于没有一个答案对我有用(我没有全部尝试)而且我在搜索中不止一次遇到这个答案......在 python 3 中,这个解决方案非常优雅,我相信它完全符合作者的要求,它更新了同一行的单个语句。请注意,如果线条缩小而不是增长,您可能需要做一些特殊的事情(比如可能使字符串成为固定长度并在末尾填充空格)

if __name__ == '__main__':
    for i in range(100):
        print("", end=f"\rPercentComplete: {i} %")
        time.sleep(0.2)

【讨论】:

  • python 最简单和最干净的选项 => 3.6
【解决方案7】:

这对我有用,破解了一次,看看是否可行,但从未在我的程序中实际使用过(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')

【讨论】:

    【解决方案8】:
    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)
    

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

    使用 Python 2.7 在 Windows cmd 上测试

    【讨论】:

      【解决方案9】:

      如果您使用的是 Spyder,则这些行将与之前的所有解决方案一起连续打印。避免这种情况的一种方法是使用:

      for i in range(1000):
          print('\r' + str(round(i/len(df)*100,1)) + '% complete', end='')
          sys.stdout.flush()
      

      【讨论】:

      • 这是我唯一可行的解​​决方案(Python 3.8、Windows、PyCharm)。
      【解决方案10】:

      截至 2020 年底,Linux 控制台上的 Python 3.8.5 仅适用于我:

      print('some string', end='\r')

      归功于:This post

      【讨论】:

        【解决方案11】:

        试试这样:

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

        (末尾有逗号。)

        【讨论】:

        • 这只是将新文本附加到旧文本(功能相似但丑陋)。
        【解决方案12】:

        对于 Python 3+

        for i in range(5):
            print(str(i) + '\r', sep='', end ='', file = sys.stdout , flush = False)
        

        【讨论】:

          【解决方案13】:

          基于Remi answerPython 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)
          

          【讨论】:

            【解决方案14】:

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

            注意:请注意,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)
            
            

            【讨论】:

              【解决方案15】:

              如果您使用的是 Python 3 那么这是给你的,它确实有效。

              print(value , sep='',end ='', file = sys.stdout , flush = False)
              

              【讨论】:

                【解决方案16】:

                我自己想出了这个来显示倒计时,但它也适用于百分比。

                import time
                #Number of seconds to wait
                i=15
                #Until seconds has reached zero
                while i > -1:
                    #Ensure string overwrites the previous line by adding spaces at end
                    print("\r{} seconds left.   ".format(i),end='')
                        time.sleep(1)
                        i-=1
                    print("") #Adds newline after it's done
                

                只要 '/r' 之后的任何内容与前一个字符串的长度相同或更长(包括空格),它就会在同一行覆盖它。只需确保包含 end='' 否则它将打印到换行符。希望对您有所帮助!

                【讨论】:

                  【解决方案17】:

                  对于提供 StartRunning()、StopRunning() 的对象“pega”, 布尔 getIsRunning() 和整数 getProgress100() 返回 值在 0 到 100 的范围内,这提供了文本进度条 跑步时...

                  now = time.time()
                  timeout = now + 30.0
                  last_progress = -1
                  
                  pega.StartRunning()
                  
                  while now < timeout and pega.getIsRunning():
                      time.sleep(0.5)
                      now = time.time()
                  
                      progress = pega.getTubProgress100()
                      if progress != last_progress:
                          print('\r'+'='*progress+'-'*(100-progress)+' ' + str(progress) + "% ", end='', flush=True)
                          last_progress = progress
                  
                  pega.StopRunning()
                  
                  progress = pega.getTubProgress100()
                  print('\r'+'='*progress+'-'*(100-progress)+' ' + str(progress) + "% ", flush=True)
                  

                  【讨论】:

                    【解决方案18】:

                    截至 2021 年,对于 Python 3.9.0,以下解决方案在 Windows 10 Pycharm 中适用于我。

                    print('\r some string ', end='', flush=True)

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2023-01-27
                      • 1970-01-01
                      • 2022-01-16
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多