प्रिंट फ़ंक्शन का आउटपुट फ्लश कैसे करें?


1215

मैं स्क्रीन पर आउटपुट करने के लिए पायथन के प्रिंट फ़ंक्शन को कैसे मजबूर करूं?

यह डिसेबल आउटपुट बफ़रिंग का डुप्लिकेट नहीं है - लिंक किया गया प्रश्न अप्रतिबंधित आउटपुट का प्रयास कर रहा है, जबकि यह अधिक सामान्य है। उस प्रश्न के शीर्ष उत्तर बहुत शक्तिशाली या इस एक के लिए शामिल हैं (वे इसके लिए अच्छे उत्तर नहीं हैं), और यह प्रश्न Google पर एक रिश्तेदार नौसिखिया द्वारा पाया जा सकता है।

जवाबों:


1425

पायथन 3 पर, printएक वैकल्पिक flushतर्क ले सकते हैं

print("Hello world!", flush=True)

अजगर 2 पर आपको करना होगा

import sys
sys.stdout.flush()

कॉल करने के बाद print। डिफ़ॉल्ट रूप से, printप्रिंट करता है sys.stdout( फ़ाइल ऑब्जेक्ट के बारे में अधिक जानकारी के लिए दस्तावेज़ देखें )।


346

चल रहा है python -h, मुझे एक कमांड लाइन विकल्प दिखाई दे रहा है :

-u: असंबद्ध बाइनरी stdout और stderr; PYTHONUNBUFFERED = x '-u' से संबंधित आंतरिक बफ़रिंग के विवरण के लिए मैन पेज देखें

यहाँ प्रासंगिक डॉक्टर है


320

पायथन 3.3 के बाद से, आप print()उपयोग करने की आवश्यकता के बिना सामान्य फ़ंक्शन को फ्लश करने के लिए मजबूर कर सकते हैं sys.stdout.flush(); बस "फ्लश" कीवर्ड तर्क को सही पर सेट करें। से प्रलेखन :

प्रिंट (* ऑब्जेक्ट्स, एसईपी = '', अंत = '\ n', फ़ाइल = sys.stdout, फ्लश = झूठी)

ऑब्जेक्ट्स को स्ट्रीम फ़ाइल में प्रिंट करें, sep द्वारा अलग किया गया और अंत तक। sep, end और file, यदि मौजूद है, तो कीवर्ड तर्क के रूप में दिया जाना चाहिए।

सभी गैर-कीवर्ड तर्क स्ट्रिंग्स () की तरह स्ट्रिंग्स में बदल जाते हैं और स्ट्रीम से लिखे जाते हैं, sep द्वारा अलग किए जाते हैं और अंत के बाद। सीप और एंड दोनों को तार होना चाहिए; वे कोई भी नहीं हो सकते हैं, जिसका अर्थ डिफ़ॉल्ट मानों का उपयोग करना है। यदि कोई वस्तु नहीं दी जाती है, तो प्रिंट () सिर्फ अंत लिखेगा।

फ़ाइल तर्क एक लिखने (स्ट्रिंग) विधि के साथ एक वस्तु होनी चाहिए; यदि यह मौजूद नहीं है या कोई नहीं है, तो sys.stdout का उपयोग किया जाएगा। चाहे आउटपुट बफ़र किया जाता है, आमतौर पर फ़ाइल द्वारा निर्धारित किया जाता है, लेकिन यदि फ्लश कीवर्ड तर्क सही है, तो स्ट्रीम जबरन फ़्लश की जाती है।


197

पायथन प्रिंट का आउटपुट फ्लश कैसे करें?

मैं यह करने के पाँच तरीके सुझाता हूँ:

  • पायथन 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)

उन्होंने 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

आप किसी मॉड्यूल के वैश्विक दायरे पर functionalools.partial का उपयोग करके प्रिंट फ़ंक्शन के लिए डिफ़ॉल्ट बदल सकते हैं:

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

फिर से ध्यान दें, यह केवल वर्तमान वैश्विक दायरे को बदलता है, क्योंकि वर्तमान वैश्विक दायरे पर प्रिंट नाम बिलियन printफ़ंक्शन (या मौजूदा वैश्विक दायरे में पायथन 2 में से एक का उपयोग करते हुए, संगतता फ़ंक्शन को अप्रतिबंधित करेगा)।

यदि आप मॉड्यूल के वैश्विक दायरे के बजाय एक फ़ंक्शन के अंदर ऐसा करना चाहते हैं, तो आपको इसे एक अलग नाम देना चाहिए, जैसे:

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

यदि आप इसे किसी फ़ंक्शन में वैश्विक घोषित करते हैं, तो आप इसे मॉड्यूल के वैश्विक नामस्थान पर बदल रहे हैं, इसलिए आपको इसे केवल वैश्विक नामस्थान में रखना चाहिए, जब तक कि विशिष्ट व्यवहार वैसा ही न हो जैसा आप चाहते हैं।

प्रक्रिया के लिए डिफ़ॉल्ट बदलना

मुझे लगता है कि यहां सबसे अच्छा विकल्प -uझंडे का उपयोग करने के लिए असंबद्ध आउटपुट प्राप्त करना है।

$ python -u script.py

या

$ python -um package.module

से डॉक्स :

बल स्टड, stdout और stderr पूरी तरह से अप्रभावित होने के लिए। उन प्रणालियों पर जहां यह मायने रखता है, बाइनरी मोड में स्टडिन, स्टडआउट और स्टेडर भी डालते हैं।

ध्यान दें कि file.readlines () और फ़ाइल ऑब्जेक्ट्स (sys.stdin में लाइन के लिए) में आंतरिक बफरिंग है, जो इस विकल्प से प्रभावित नहीं है। इसके आसपास काम करने के लिए, आप 1: लूप के अंदर file.readline () का उपयोग करना चाहेंगे।

शेल ऑपरेटिंग वातावरण के लिए डिफ़ॉल्ट बदलना

यदि आप पर्यावरण चर को गैर-रिक्त स्ट्रिंग में सेट करते हैं, तो आप इस व्यवहार को पर्यावरण या वातावरण से प्राप्त होने वाली वातावरण की सभी प्रक्रियाओं के लिए प्राप्त कर सकते हैं:

उदाहरण के लिए, लिनक्स या OSX में:

$ 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.

निचले पायथन संस्करणों से पलायन करने वाले जिज्ञासु के लिए: __future__संस्करण में शामिल नहीं है flushक्योंकि "फ्लश तर्क को पायथन 3.3 में जोड़ा गया था (प्रिंट के बाद) भविष्य के आयात के माध्यम से 2.7 में वापस कर दिया गया था" " Bugs.python.org/issive28458
ओलिवर

69

जैसा कि इस ब्लॉग में सुझाव दिया गया है कि कोई भी sys.stdoutअप्रभावित मोड में फिर से खुल सकता है:

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

प्रत्येक stdout.writeऔर printऑपरेशन स्वचालित रूप से बाद में फ्लश हो जाएगा।


2
उबंटू 12.04 में अजगर 2.7 पर यह मुझे देता हैUnsupportedOperation: IOStream has no fileno.
drevicko

3
वूप्स, पायथन 3 पता चला। यह मुझे कोड के इस टुकड़े पर अमल नहीं करने देगा!
इकोन्स

मैं इस मुहावरे से भ्रमित हूं। ऐसा करने के बाद, अब दो फ़ाइल-जैसी ऑब्जेक्ट्स (मूल sys.stdout और नए sys.stdout) नहीं हैं कि दोनों को लगता है कि वे "स्वयं" फाइलो हैं? यह बुरा है, है ना?
डॉन हैच


36

-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एड होंगे।


4
मैं फ़ाइल से इनहेरिट नहीं करने की सलाह देता हूं और फिर जोड़कर stdout में डेलिगेट करता हूं। def __getattr__(self,name): return object.__getattribute__(self.f, name)
मृत्युंजय

2
@Diedthreetimes द्वारा टिप्पणी द्वारा सुझाए गए परिवर्तनों के बिना, मुझे "ValueError: I / O ऑपरेशन बंद फाइल पर" मिलता है
ब्लूफैस्ट

19

क्यों एक अनफ़िल्टर्ड फ़ाइल का उपयोग करने की कोशिश नहीं की?

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

या

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

1
वह नहीं चाहता है कि ओटी एक अनफ़िल्टर्ड फ़ाइल बनाएं; वह मौजूदा स्टडआउट (कंसोल, टर्मिनल या जो कुछ भी पुनर्निर्देशित करना चाहता है) को अप्रभावित करना चाहता है।
ब्लूफैस्ट

13

दान का विचार काफी काम नहीं करता है:

#!/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 के लिए:

stdout और stderr में अंतर्निहित फ़ाइल ऑब्जेक्ट्स की आवश्यकता नहीं होती है: कोई भी वस्तु तब तक स्वीकार्य होती है जब तक उसके पास एक लेखन () विधि होती है जो एक स्ट्रिंग तर्क लेती है।

इसलिए बदल रहा है

class flushfile(file):

सेवा

class flushfile(object):

यह ठीक काम करता है।


17
कोई वोट नहीं क्योंकि यह @ दान का समाधान है ... (आपको उसके समाधान की नकल करने के बजाय दान की पोस्ट पर टिप्पणी करनी चाहिए)
gecco

8

यहां मेरा संस्करण है, जो लेखन () और फाइलो () भी प्रदान करता है:

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.4.0 पर परीक्षण किया गया। अन्य संस्करणों के साथ, जो fileमुझे प्राप्त होते हैं , मुझे एक त्रुटि मिलती है। कोई fileवर्ग नहीं है ।
कॉलिन डी बेनेट ने

6

पायथन 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)

2
यह उत्तर सभी अन्य उच्च गुणवत्ता प्रतिक्रियाओं को देखते हुए थोड़ा हल्का लगता है। आप इसमें थोड़ा और जोड़ना चाह सकते हैं।
अर्धविराम और डक्ट टेप

5

मैंने इसे पायथन 3.4 में इस तरह किया:

'''To write to screen in real-time'''
message = lambda x: print(x, flush=True, end="")
message('I am flushing out now...')

2

मैं पहली बार यह समझने के लिए संघर्ष किया कि फ्लश विकल्प कैसे काम कर रहा था। मैं एक 'लोडिंग डिस्प्ले' करना चाहता था और यहां मुझे जो समाधान मिला वह है:

for i in range(100000):
    print('{:s}\r'.format(''), end='', flush=True)
    print('Loading index: {:d}/100000'.format(i+1), end='')

पहली पंक्ति पिछले प्रिंट को फ्लश करती है और दूसरी लाइन एक नए अपडेटेड संदेश को प्रिंट करती है। मुझे नहीं पता कि क्या यहां एक-लाइन सिंटैक्स मौजूद है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.