python - ইথন - ফাংশনাল প্রোগ্রামিং




প্রিন্ট ফাংশন আউটপুট ফ্লাশ কিভাবে? (10)

আমি কিভাবে পাইথন এর মুদ্রণ ফাংশন পর্দায় আউটপুট করতে বাধ্য করতে পারি?

এটি আউটপুট বাফারিং নিষ্ক্রিয়করণের একটি সদৃশ নয় - লিঙ্কযুক্ত প্রশ্নটি অপবফার আউটপুট করার চেষ্টা করছে, যখন এটি আরও সাধারণ। এই প্রশ্নের শীর্ষ উত্তরগুলি খুব শক্তিশালী বা এইরকম জড়িত (এটির জন্য এটি উত্তম উত্তর নয়), এবং এই প্রশ্নটি আপেক্ষিক নবাগত দ্বারা Google এ পাওয়া যেতে পারে।


পাইথন প্রিন্ট আউটপুট ফ্লাশ কিভাবে?

আমি এই কাজ করার পাঁচটি উপায় সুপারিশ:

  • পাইথন 3 এ, কল print(..., flush=True) (ফ্লাশ যুক্তিটি পাইথন 2 এর মুদ্রণ ফাংশনে উপলব্ধ নয় এবং মুদ্রণ বিবৃতির জন্য কোনও এনালগ নেই)।
  • আউটপুট ফাইলে file.flush() কল করুন file.flush() এটি করার জন্য আমরা পাইথন 2 এর মুদ্রণ ফাংশনটি মোড়ানো করতে পারি), উদাহরণস্বরূপ, sys.stdout
  • একটি আংশিক ফাংশন সঙ্গে মডিউল প্রতি মুদ্রণ ফাংশন কল এই প্রয়োগ করুন,
    print = partial(print, flush=True) মডিউল গ্লোবাল প্রয়োগ।
  • একটি পতাকা ( -u ) দিয়ে ইন্টারপ্রেটার কমান্ডে পাস করে প্রক্রিয়াটি প্রয়োগ করুন
  • PYTHONUNBUFFERED=TRUE (এবং এটি পূর্বাবস্থায় ফিরিয়ে আনতে পরিবর্তনশীলটি সেট না করে) আপনার পরিবেশে প্রতিটি পাইথন প্রক্রিয়াতে এটি প্রয়োগ করুন।

পাইথন 3.3+

পাইথন 3.3 বা উচ্চতর ব্যবহার করে, আপনি শুধুমাত্র print ফাংশনে কীওয়ার্ড যুক্তি হিসাবে flush=True করতে পারেন:

print('foo', flush=True) 

পাইথন 2 (অথবা <3.3)

তারা পাইথন flush যুক্তি সমর্থন করে না। 7 তাই যদি আপনি পাইথন ২ (অথবা 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.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

docs থেকে:

Stdin, stdout এবং stderr জোর সম্পূর্ণরূপে unbuffered করা। সিস্টেমে যেখানে এটি গুরুত্বপূর্ণ, বাইনারি মোডে stdin, stdout এবং stderrও রাখুন।

ফাইল.readlines () এবং ফাইল অবজেক্টস (sys.stdin- র লাইনের জন্য) এ অভ্যন্তরীণ বাফারিং মনে রাখবেন যা এই বিকল্প দ্বারা প্রভাবিত নয়। এটির জন্য কাজ করার জন্য, আপনি file.readline () ব্যবহার করতে চান কিছুক্ষণের মধ্যে 1: লুপ।

শেল অপারেটিং পরিবেশের জন্য ডিফল্ট পরিবর্তন

আপনি পরিবেশগত ভেরিয়েবলটি একটি nonempty স্ট্রিংয়ের জন্য সেট করলে পরিবেশ থেকে উত্তরাধিকারী পরিবেশ বা পরিবেশগুলিতে সমস্ত পাইথন প্রক্রিয়াগুলির জন্য এই আচরণটি পেতে পারেন:

উদাহরণস্বরূপ, লিনাক্স বা ওএসএক্সে:

$ export PYTHONUNBUFFERED=TRUE

অথবা উইন্ডোজ:

C:\SET PYTHONUNBUFFERED=TRUE

docs থেকে:

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.

Python 3.3 থেকে, আপনি সাধারন print() ফাংশনটি sys.stdout.flush() ব্যবহার করার প্রয়োজন ছাড়াই ফ্লাশ করতে বাধ্য করতে পারেন; শুধু সত্য "flush" শব্দ যুক্তি সেট। ডকুমেন্টেশন থেকে:

মুদ্রণ করুন (* বস্তু, sep = '', end = '\ n', file = sys.stdout, flush = false)

প্রবাহ বস্তু মুদ্রণ ফাইল, sep দ্বারা পৃথক এবং শেষে দ্বারা অনুসরণ। sep, end এবং ফাইল, যদি উপস্থিত থাকে তবে অবশ্যই কীওয়ার্ড আর্গুমেন্ট হিসাবে দেওয়া হবে।

সমস্ত অ-কীওয়ার্ড আর্গুমেন্টগুলি str () এর মতো স্ট্রিংগুলিতে রূপান্তরিত হয় এবং স্ট্রীমে লিখিত হয়, সিপি দ্বারা আলাদা করে এবং শেষ অনুসারে অনুসরণ করে। উভয় sep এবং শেষ স্ট্রিং হতে হবে; তারা কোনও হতে পারে না, যা ডিফল্ট মানগুলি ব্যবহার করতে পারে। কোন বস্তু দেওয়া হয় না, তাহলে মুদ্রণ () শুধুমাত্র লিখতে হবে।

ফাইল আর্গুমেন্টটি একটি বস্তুর একটি লেখার (স্ট্রিং) পদ্ধতি অবশ্যই হতে হবে; যদি এটি বর্তমান না হয় না, sys.stdout ব্যবহার করা হবে। আউটপুট buffered হয় কিনা সাধারণত ফাইল দ্বারা নির্ধারিত হয়, কিন্তু ফ্লাশ শব্দ যুক্তি সত্য হলে, প্রবাহ জোরপূর্বক flushed হয়।


এখানে আমার সংস্করণ, যা লেখালিখন () এবং 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()

এছাড়াও এই ব্লগে প্রস্তাবিত হিসাবে unbuffered মোডে sys.stdout পুনরায় খুলতে পারে:

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

প্রতিটি stdout.write এবং print অপারেশন স্বয়ংক্রিয়ভাবে পরে flushed হবে।


চলমান python -h , আমি একটি কমান্ড লাইন বিকল্প দেখি:

-u: unbuffered বাইনারি stdout এবং stderr; এছাড়াও পাইথনউনফুফেড = x '-u' সম্পর্কিত অভ্যন্তরীণ বাফারিং সম্পর্কিত বিস্তারিত জানার জন্য ম্যান পৃষ্ঠা দেখুন

এখানে প্রাসঙ্গিক ডক


ড্যান এর ধারণা বেশ কাজ করে না:

#!/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):

এটা ঠিক জরিমানা কাজ করে তোলে।


পাইথন 3.x দিয়ে print() ফাংশন প্রসারিত হয়েছে:

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

সুতরাং, আপনি শুধু করতে পারেন:

print("Visiting toilet", flush=True)

পাইথন ডক্স এন্ট্রি


প্রিয় ড্যানের সমাধান! পাইথন 3 এর জন্য:

import io,sys
class flushfile:
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()
sys.stdout = flushfile(sys.stdout)

import sys
print 'This will be output immediately.'
sys.stdout.flush()





flush