2010-09-14 49 views
3

我有一個使用curses的程序,然後返回到主腳本以作進一步處理。它返回後,我的後續輸出到標準輸出不會出現,直到它有大量(例如數千字節)。Python stdout在調用curses後無法正確刷新

我已經減少了問題的一個非常簡單的程序,無法可靠:「你好!世界

import curses 
import time 

curses.initscr() 
curses.endwin() 

print "Hello world!" 
time.sleep(5) 

如果我註釋掉兩個詛咒呼叫,在延遲之前打印。如果我將它們放入,它將在延遲後打印(當腳本退出時)。

+0

可能重複[?如何刷新蟒紋的輸出(http://stackoverflow.com/questions/230751/how-to-flush-output-of- python-print) – Jack 2010-09-14 04:08:24

+0

@jack。不。這涉及爲什麼輸出緩衝區需要首先被刷新 – aaronasterling 2010-09-14 04:35:58

+0

好的,對不起。試圖幫助將OP指向可能有用的東西! – Jack 2010-09-14 23:58:54

回答

3

curses.endwin()調用「設置標準I/O恢復正常」......不幸意味着「緩衝」(您可以考慮在curses中發現一個錯誤並將錯誤提交給Python的跟蹤器)。

爲了確保標準輸出緩衝,

import os 

sys.stdout = os.fdopen(0, 'w', 0) 

(你可以把import os在開始或過程;的sys.stdout調動是爲了去endwin調用後右)。

+0

那麼標準輸出是否如同無緩衝地開始生命?我認爲這就是-u標誌的用意。但是,是的,這個修復工作,謝謝。 – 2010-09-14 05:10:19

+0

究竟是「標準I/O恢復正常」?我在Python文檔,curses模塊源代碼或endwin手冊頁(curs_initscr(3X))中沒有看到。 – jwelsh 2017-03-01 18:45:44

0

我發現這是依賴於系統/庫。在我的Windows機器上(詛咒來自http://www.lfd.uci.edu/~gohlke/pythonlibs/)它會沖洗然後睡覺,但是在Linux上它會在睡眠後沖洗。我想你可以簡單地使用:sys.stdout.flush()像:

print "Hello world!" 
sys.stdout.flush() 
time.sleep(5) 

(它可能是更好的做出某種「打印&刷新」功能)

1

亞歷克斯打我給它(他知道,我不得不弄明白了)但我寫了這個漂亮的上下文管理器,你可以使用。

import curses 
import time 
import os 
import sys 


class CursesStdout(object): 
    def __enter__(self): 
     pass 

    def __exit__(self, *args): 
     sys.stdout = sys.__stdout__ = os.fdopen(sys.__stdout__.fileno(), 'w', 0) 

with CursesStdout(): 
    curses.initscr() 
    curses.endwin() 


print "Hello world!" 
time.sleep(2) 

我直接修改sys.__stdout__因爲當你在curses/__init__.py看看源,你看到initscr函數傳遞的是文件描述符的C代碼,所以我存儲要恢復至正常。

+0

這也不錯,但我不能使用它,因爲這個項目是在Python 2.4上。謝謝,不過。 – 2010-09-14 05:17:51

1

更清晰的方式:

import sys 
import curses 

correct_stdout = sys.stdout # remember correct 

curses.initscr() 
curses.endwin() 

sys.stdout = correct_stdout # restore correct 
+2

如果你能解釋一下你的答案,那該多好。 – RatDon 2015-03-26 05:55:49