سؤال

كيف يمكنني القوة بايثون وظيفة الطباعة إلى الإخراج إلى الشاشة ؟

هذه ليست نسخة مكررة من تعطيل التخزين المؤقت الإخراج - مرتبط السؤال هو محاولة unbuffered الإخراج ، في حين أن هذا هو أكثر العامة.أفضل الإجابات على هذا السؤال هي قوية جدا أو تشارك هذه (أنهم لا إجابات شافية عن هذا) و هذا السؤال يمكن العثور عليها على جوجل النسبية مبتدئ.

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

المحلول

import sys
sys.stdout.flush()

print بشكل افتراضي يطبع sys.stdout.

المراجع

بيثون 2

بيثون 3

نصائح أخرى

وتشغيل python -h، أرى <م> خيار سطر الأوامر :

<اقتباس فقرة>   

و-u: غير مصقول المعياري ثنائي وستدير. أيضا PYTHONUNBUFFERED = س            راجع صفحة الرجل لمزيد من التفاصيل على التخزين المؤقت الداخلية المتعلقة '-u'

وهنا هو ثيقة الصلة .

منذ الثعبان 3.3 يمكنك فرض العادي print() وظيفة لطرد دون الحاجة إلى استخدام sys.stdout.flush();فقط تعيين "دافق" كلمات حجة إلى true.من الوثائق:

طباعة(*الكائنات ، sep=' ', end=' ', file=sys.المعياري ، دافق=False)

طباعة الكائنات إلى تيار الملف ، مفصولة sep و تليها الغاية.سبتمبر, نهاية الملف, إذا كان موجودا, يجب أن تعطى الكلمة الحجج.

غير الكلمة الحجج يتم تحويلها إلى سلاسل مثل str() هل وكتب إلى تيار مفصولة sep و تليها الغاية.سواء سبتمبر ونهاية يجب أن تكون سلاسل ؛ يمكن أيضا أن تكون لا شيء ، مما يعني أن استخدام القيم الافتراضية.إذا لم الأجسام يعطى طباعة() فقط أكتب نهاية.

الملف يجب أن يكون حجة كائن مع كتابة(سلسلة) الأسلوب ؛ إذا لم يكن موجودا أو لا شيء ، sys.stdout سيتم استخدامها. إذا كان الناتج هو مخزنة عادة ما تحددها الملف ، ولكن إذا كان تدفق الكلمة حجة صحيحة ، ستريم قسرا مسح.

كيفية تنظيف إخراج الثعبان الطباعة ؟

أقترح خمسة طرق للقيام بذلك:

  • في بيثون 3, دعوة print(..., flush=True) (دافق الحجة ليست متوفرة في بيثون 2 وظيفة الطباعة ، وليس هناك التماثلية الطباعة البيان).
  • الاتصال file.flush() على الملف الناتج (ونحن يمكن أن التفاف الثعبان 2 وظيفة الطباعة للقيام بذلك) ، على سبيل المثال ، sys.stdout
  • ينطبق هذا على كل طباعة استدعاء دالة في وحدة مع وظيفة جزئية,
    print = partial(print, flush=True) تطبيق وحدة العالمية.
  • تطبيق هذه العملية مع العلم (-u) مرت إلى مترجم الأوامر
  • ينطبق هذا على كل عملية الثعبان في البيئة الخاصة بك مع PYTHONUNBUFFERED=TRUE (و ضبطه المتغير إلى التراجع عن هذا).

بيثون 3.3+

باستخدام بيثون 3.3 أو أعلى يمكنك توفير flush=True كما الكلمة حجة على print وظيفة:

print('foo', flush=True) 

بيثون 2 (أو < 3.3)

لم backport على flush حجة بايثون 2.7 حتى إذا كنت تستخدم بايثون 2 (أو أقل من 3.3), و أريد كود متوافق مع كل من 2 و 3 و قد أقترح التوافق التالية التعليمات البرمجية.(ملاحظة __future__ استيراد يجب أن يكون في/جدا "بالقرب من العلوي من الوحدة النمطية الخاص بك"):

from __future__ import print_function
import sys

if sys.version_info[:2] < (3, 3):
    old_print = print
    def print(*args, **kwargs):
        flush = kwargs.pop('flush', False)
        old_print(*args, **kwargs)
        if flush:
            file = kwargs.get('file', sys.stdout)
            # Why might file=None? IDK, but it works for print(i, file=None)
            file.flush() if file is not None else sys.stdout.flush()

سبق التوافق رمز سوف تغطي معظم الاستخدامات ، ولكن أكثر من ذلك بكثير شامل العلاج ، ترى six وحدة.

بدلا من ذلك, يمكنك فقط الاتصال file.flush() بعد الطباعة ، على سبيل المثال ، مع طباعة البيان في بيثون 2:

import sys
print 'delayed output'
sys.stdout.flush()

تغيير الافتراضي في وحدة واحدة إلى flush=True

يمكنك تغيير الإعدادات الافتراضية وظيفة الطباعة باستخدام functools.جزئية على نطاق عالمي من وحدة:

import functools
print = functools.partial(print, flush=True)

إذا كنت تبحث في وظيفة جزئية على الأقل في بيثون 3:

>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)

يمكننا أن نرى أنها تعمل تماما مثل العادية:

>>> print('foo')
foo

و يمكننا في الواقع تجاوز الافتراضي الجديد:

>>> print('foo', flush=False)
foo

ملاحظة ثانية, هذا فقط التغيرات العالمية الحالية نطاق ، لأن طباعة الاسم على الحالية النطاق العالمي سوف تلقي بظلالها على builtin print وظيفة (أو إلغاء مرجعية التوافق وظيفة ، إذا كان استخدام بيثون 2 في هذا النطاق العالمي).

إذا كنت تريد أن تفعل هذا داخل وظيفة بدلا من وحدة العالمية النطاق ، يجب أن تعطيه اسم مختلف على سبيل المثال:

def foo():
    printf = functools.partial(print, flush=True)
    printf('print stuff like this')

إذا كنت تعلن شركة عالمية في وظيفة أنت تغيير على وحدة مساحة العالمي ، لذلك يجب أن أضعها في مساحة العالمي ، إلا أن سلوك معين هو بالضبط ما تريد.

تغيير الافتراضي للعملية

أعتقد أن الخيار الأفضل هنا هو استخدام -u العلم للحصول على unbuffered الانتاج.

$ python -u script.py

أو

$ python -um package.module

من مستندات:

قوة stdin ، المعياري و stderr تماما unbuffered.على أنظمة حيث يهم أيضا وضع stdin ، المعياري و stderr في الوضع الثنائي.

علما أن هناك الداخلية التخزين المؤقت في الملف.readlines() و الملف الكائنات (على الخط في sys.stdin) الذي لا يتأثر هذا الخيار.كمحاولة للتغلب على هذه, سوف تحتاج إلى استخدام الملف.readline() داخل بعض الوقت 1:حلقة.

تغيير الافتراضي قذيفة بيئة التشغيل

يمكنك الحصول على هذا السلوك لجميع الثعبان العمليات في بيئة أو بيئات التي تكتسب من البيئة إذا قمت بتعيين متغير البيئة إلى خاليا سلسلة:

على سبيل المثال, في لينكس أو ماك:

$ export PYTHONUNBUFFERED=TRUE

أو ويندوز:

C:\SET PYTHONUNBUFFERED=TRUE

من مستندات:

PYTHONUNBUFFERED

إذا تم تعيين إلى غير فارغة وهو ما يعادل تحديد -u الخيار.


الإضافة

هنا هو المساعدة على وظيفة الطباعة من بيثون 2.7.12 - لاحظ أن هناك لا flush الحجة:

>>> from __future__ import print_function
>>> help(print)
print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout)

    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file: a file-like object (stream); defaults to the current sys.stdout.
    sep:  string inserted between values, default a space.
    end:  string appended after the last value, default a newline.

وأيضا كما هو مقترح في هذا بلوق يمكن للمرء أن إعادة فتح sys.stdout في وضع غير مصقول:

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

وسوف يتم مسح كل عملية stdout.write وprint تلقائيا بعد ذلك.

ومع بيثون 3.X وقد تم تمديد وظيفة print():

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

وهكذا، يمكنك أن تفعل فقط:

print("Visiting toilet", flush=True)

بايثون مستندات الدخول

وعن طريق أعمال التبديل -u سطر الأوامر، ولكنه أخرق قليلا. فإن ذلك يعني أن البرنامج من المحتمل أن تتصرف بشكل غير صحيح إذا استدعاء المستخدم النصي بدون خيار -u. وعادة ما تستخدم stdout مخصصة، مثل هذا:

class flushfile:
  def __init__(self, f):
    self.f = f

  def write(self, x):
    self.f.write(x)
    self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

... الآن جميع المكالمات print الخاص بك (التي تستخدم sys.stdout ضمنا)، سيتم flushed تلقائيا.

لماذا لا نحاول استخدام ملف غير مصقول؟

f = open('xyz.log', 'a', 0)

وOR

sys.stdout = open('out.log', 'a', 0)

وفكرة دان يفعل العمل ليس تماما:

#!/usr/bin/env python
class flushfile(file):
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

print "foo"

والنتيجة:

Traceback (most recent call last):
  File "./passpersist.py", line 12, in <module>
    print "foo"
ValueError: I/O operation on closed file

وأعتقد أن المشكلة هي أنه يرث من فئة الملف، والذي هو في الواقع ليس من الضروري. ووفقا للمستندات لsys.stdout:

<اقتباس فقرة>   

والمعياري وستدير ليس من الضروري أن تكون مدمجة في   ملف قطع: أي كائن غير مقبول   طالما أنه يحتوي على الكتابة طريقة ()   التي تأخذ وسيطة سلسلة.

وحتى تغيير

class flushfile(file):

إلى

class flushfile(object):

ويجعلها تعمل على ما يرام.

وهنا هو بلدي النسخة، التي تنص على writelines () وfileno ()، وأيضا:

class FlushFile(object):
    def __init__(self, fd):
        self.fd = fd

    def write(self, x):
        ret = self.fd.write(x)
        self.fd.flush()
        return ret

    def writelines(self, lines):
        ret = self.writelines(lines)
        self.fd.flush()
        return ret

    def flush(self):
        return self.fd.flush

    def close(self):
        return self.fd.close()

    def fileno(self):
        return self.fd.fileno()

في بيثون 3 يمكنك الكتابة وظيفة الطباعة مع مجموعة افتراضية لflush = True

def print(*objects, sep=' ', end='\n', file=sys.stdout, flush=True):
    __builtins__.print(*objects, sep=sep, end=end, file=file, flush=flush)

وأنا فعلت هذا من هذا القبيل في بيثون 3.4:

'''To write to screen in real-time'''
message = lambda x: print(x, flush=True, end="")
message('I am flushing out now...')
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top