Python stdout لا يتدفق بشكل صحيح بعد استدعاء اللعنات
سؤال
لديّ برنامج يستخدم اللعنات ، ثم يعود إلى البرنامج النصي الرئيسي لمزيد من المعالجة. بعد عودته ، لا يظهر مخرجاتي اللاحقة إلى 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)
(قد يكون من الأفضل صنع نوع من وظيفة "الطباعة والتدفق")