Python STDOUT не промывает правильно после вызова проклятий
Вопрос
У меня есть программа, которая использует Curses, а затем возвращается к главному сценарию для дальнейшей обработки. После возвращения на мой последующий вывод на STDOUT не появляется до тех пор, пока не будет многое количество (например, тысячи байтов).
Я сократил проблему в очень простую программу, которая надежно не удается:
import curses
import time
curses.initscr()
curses.endwin()
print "Hello world!"
time.sleep(5)
Если я прокомментирую два звонка проклятия, «Hello World!» печатает перед задержкой. Если я введу их, он печатает после задержки (когда сценарий выходит).
Решение
То curses.endwin()
Позвоните «Устанавливает стандартный ввод / вывод к нормальному» ... что к сожалению означает «буферизованный» (вы могли бы рассмотреть, что ошибка в curses
и подать ошибку на трекере Python).
Для обеспечения небуферизации стандартного вывода,
import os
sys.stdout = os.fdopen(0, 'w', 0)
(Вы можете поставить import os
в начале или курс; переназначение sys.stdout
предназначен для того, чтобы идти сразу после endwin
вызов).
Другие советы
Алекс избил меня к этому (он знал, что мне пришлось понять это), но я написал этот нефте-менеджер контекста, который вы сможете использовать.
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-коду и так, чтобы я хранил, что для сброса к нормальному.
Более понятный способ:
import sys
import curses
correct_stdout = sys.stdout # remember correct
curses.initscr()
curses.endwin()
sys.stdout = correct_stdout # restore correct
Я обнаружил, что TIS - это система системы / библиотеки. На моем Windows Machine (проклятия от http://www.lfd.uci.edu/~gohlke/pythonlibs/) Это смывается, а затем спит, но на Linux он промывает после сна. Я думаю, что вы можете просто использовать: sys.stdout.flush()
нравится:
print "Hello world!"
sys.stdout.flush()
time.sleep(5)
(Возможно, лучше сделать какой-то функцию «Print & Flush»)