Python STDOUT не промывает правильно после вызова проклятий

StackOverflow https://stackoverflow.com/questions/3706066

  •  02-10-2019
  •  | 
  •  

Вопрос

У меня есть программа, которая использует 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»)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top