2017-08-08 78 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