Python stdout لا يتدفق بشكل صحيح بعد استدعاء اللعنات

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

  •  02-10-2019
  •  | 
  •  

سؤال

لديّ برنامج يستخدم اللعنات ، ثم يعود إلى البرنامج النصي الرئيسي لمزيد من المعالجة. بعد عودته ، لا يظهر مخرجاتي اللاحقة إلى stdout حتى يكون هناك كمية كبيرة منه (على سبيل المثال آلاف البايتات).

لقد خفضت المشكلة إلى برنامج بسيط للغاية يفشل بشكل موثوق:

import curses
import time

curses.initscr()
curses.endwin()

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

إذا علقت على مكالمات اللعنتين ، "Hello World!" يطبع قبل التأخير. إذا وضعتهم ، فإنه يطبع بعد التأخير (عندما يخرج البرنامج النصي).

هل كانت مفيدة؟

المحلول

ال curses.endwin() استدعاء "تعيين I/O القياسي إلى Normal" ... مما يعني للأسف "مخزنة" (يمكنك التفكير في ذلك الخلل في curses وقم بتقديم الخلل على تعقب بيثون).

لضمان عدم إخراج الإخراج القياسي ،

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 ولذا فإنني أقوم بتخزين ذلك لإعادة تعيينه إلى Normal.

طريقة أكثر وضوحا:

import sys
import curses

correct_stdout = sys.stdout    # remember correct

curses.initscr()
curses.endwin()

sys.stdout = correct_stdout    # restore correct

لقد وجدت أن TIS يعتمد على النظام/المكتبة. على جهاز Windows الخاص بي (اللعنات من http://www.lfd.uci.edu/~gohlke/pythonlibs/) إنه ينام ثم ينام ، ولكن على Linux يطرد بعد النوم. أعتقد أنه يمكنك ببساطة استخدام: sys.stdout.flush() مثل:

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

(قد يكون من الأفضل صنع نوع من وظيفة "الطباعة والتدفق")

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top