2017-08-08 95 views
6

TL; DR:使用print()太多会导致失败?

print()结果不会在Windows控制台更新。在IDLE中执行得很好。即使Windows控制台未更新,程序仍在执行。

背景

我有一个文件,test.py包含:

编辑:包括我来看看控制台正在更新的条件。最终,系列X值在控制台中再也不会再次打印,并且控制台也不会再次向上滚动(正如在底部生成输出时一样)。

count = 0 
while True: 
    print ("True") 
    count += 1 
    if count == 10: 
      print ("XXXXXXXXX") 
      count = 0 

当我在cmd.exe运行这个它显然打印大量的True

但是,运行约25秒后,它会停止打印,尽管程序仍在运行并可在任务管理器中看到。

我有一个程序,有一些进度指标,最终停留在50%,即使它们远远超过50%,因为print()没有显示在控制台输出中。

编辑:真正的用例问题。

上面的代码只是一个测试文件,看看在控制台中打印是否停在所有程序中,而不是我正在运行的程序中。在实践中,我的程序打印到控制台,看起来像:

line [10] >> Progress 05% 

哪里line [10]真正但我只是在这里输入的告诉你,print()发送到在控制台窗口中该行。随着我的程序继续增量:

line [10] >> Progress 06% 
line [10] >> Progress 11% 
. 
. 
. 
line [10] >> Progress 50% 

每次都会覆盖line [10]。我使用ANSI转义字符和colorama相应移动控制台光标:

print('\x1b[1000D\x1b[1A')

这将光标移到1000列左右1行了(所以前行的开始)。

又出事了其中print("Progress " + prog + "%")因为最终的Python的下一位被执行不控制台显示了起来:

line [11] >> Program Complete...

我验证了其中获得放入文件夹中的生成物。所以程序继续运行,而控制台没有更新。

编辑:以下是运行stdout更新的脚本。

def check_queue(q, dates, dct): 
    out = 0 
    height = 0 

    # print the initial columns and rows of output 
    # each cell has a unique id 
    # so they are stored in a dictionary 
    # then I convert to list to print by subscripting 
    for x in range(0, len(list(dct.values())), 3): 
     print("\t\t".join(list(dct.values())[x:x+3])) 
     height +=1 # to determine where the top is for cursor 

    while True: 
     if out != (len(dates) * 2): 
      try: 
       status = q.get_nowait() 
       dct[status[1]] = status[2] 
       print('\x1b[1000D\x1b[' + str(height + 1) + 'A') 

       # since there was a message that means a value was updated 
       for x in range(0, len(list(dct.values())), 3): 
        print("\t\t".join(list(dct.values())[x:x+3])) 

       if status[0] == 'S' or 'C' or 'F': 
        out += 1 
      except queue.Empty: 
       pass 
    else: 
     break 

简而言之,我将消息从线程传递到队列。然后我更新一个包含唯一单元ID的字典。我更新该值,将控制台中的光标移动到打印列表的左上角位置,然后在其上打印。

问:

当使用标准输出,有没有办法可以多少次打印到它在一段时间有限制吗?

+4

是什么让你觉得它停止打印? – user2357112

+3

Python当然对进程可以产生多少输出没有限制。 –

+0

@ user2357112现在查看代码块。我更新了它与我如何测试以确保这一点。最终发生的事情是'X'系列再也不会出现,并且控制台从不滚动上一个输出。这导致我相信它不再打印。 – datta

回答

4

这可能是一种错觉(也许是因为控制台中有最大限度的行数,而新的行数只会替换第一行数)。

有多少你可以print限制没有限制。你可以有一些改变每次迭代,例如验证这一个循环计数的迭代次数:

import itertools 
for i in itertools.count(): 
    print(i, "True") 
+0

我开始认为这可能是达到行数的情况。但是,我在同一个地方覆盖了一些行。它是重复计数吗? – datta

+0

我不明白你的意思。一些控制台像FIFO队列一样工作,当达到一定的限制时,他们丢弃最早的行来打印最新的行。就像我在答案中提到的那样。但是无论如何,如果这不能解决你的问题并解释**为什么它不能解决你的问题,你能否更新你的问题? – MSeifert

+0

请参阅我的文章编辑我的使用案例 – datta

1

听起来像它可能是一个系统的限制,而不是一个Python程序问题?我从来没有穿过运行“挂”相关打印报表(或任何内置的功能),但你可能要在映射的性能和内存使用情况看:

High Memory Usage Using Python Multiprocessing

至于多少您可以在一段时间内进行打印,这几乎完全取决于系统执行代码的速度。您可以在多个平台上运行一些基准测试(执行时间/执行次数),以测试特定系统规格的性能,但我认为您的问题的可能原因是与系统/环境相关。

2

我无法在Windows 10中使用64位Python 3.6.2和colorama 0.3.9重现该问题。以下是我测试的一个简单示例:

import colorama 
colorama.init() 

def test(M=10, N=1000): 
    for x in range(M): 
     print('spam') 
    for n in range(N): 
     print('\x1b[1000D\x1b[' + str(M + 1) + 'A') 
     for m in range(M): 
      print('spam', m, n) 

每次通过都会成功覆盖前面的行。下面是从循环N(1000)次最终输出:

>>> test() 
spam 0 999 
spam 1 999 
spam 2 999 
spam 3 999 
spam 4 999 
spam 5 999 
spam 6 999 
spam 7 999 
spam 8 999 
spam 9 999 

如果这个例子,你失败了,请更新您的问题,包括你正在测试的Windows中,Python的版本,和彩色光。

+0

我使用Windows 7,Python 3.6.0和最新版本的colorama。有趣的是,即使没有使用coloroma功能,最终stdout在控制台中停止更新(例如问题中的'while'循环)。 – datta

+0

这个答案中的例子呢? – eryksun

相关问题