كيفية تنظيف إخراج الطباعة وظيفة ؟
-
04-07-2019 - |
سؤال
كيف يمكنني القوة بايثون وظيفة الطباعة إلى الإخراج إلى الشاشة ؟
هذه ليست نسخة مكررة من تعطيل التخزين المؤقت الإخراج - مرتبط السؤال هو محاولة unbuffered الإخراج ، في حين أن هذا هو أكثر العامة.أفضل الإجابات على هذا السؤال هي قوية جدا أو تشارك هذه (أنهم لا إجابات شافية عن هذا) و هذا السؤال يمكن العثور عليها على جوجل النسبية مبتدئ.
المحلول
import sys
sys.stdout.flush()
print
بشكل افتراضي يطبع sys.stdout
.
المراجع
بيثون 2
بيثون 3
print()
sys.stdout
- كائن الملف - معجم
io.IOBase.flush()
(sys.stdout
يرثflush
طريقة منio.IOBase
)
نصائح أخرى
وتشغيل 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
ضمنا)، سيتم flush
ed تلقائيا.
لماذا لا نحاول استخدام ملف غير مصقول؟
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...')