Sys.stdout.write और प्रिंट के बीच अंतर?


375

क्या ऐसे हालात हैं sys.stdout.write() बेहतर हो print?

( उदाहरण: बेहतर प्रदर्शन; कोड जो अधिक समझ में आता है)


4
पायथन का कौन सा संस्करण? 2. x या 3. x?
मार्क बायर्स

ईमानदारी से मैं दोनों के लिए जानना चाहूंगा, हालांकि मुझे पायथन 3 के साथ कोई अनुभव नहीं है।
जोहाना लार्सन

17
@ एस.लॉट: sys.stdout.write()और print(और / या क्यों पायथन दोनों के बीच बुनियादी अंतर है ) के लिए पूछना एक पूरी तरह से उचित सवाल है और उदाहरण की आवश्यकता नहीं है। ओपी ने यह नहीं कहा कि कमांड सिंटैक्स भ्रामक था।
22

जवाबों:


293

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

print >> open('file.txt', 'w'), 'Hello', 'World', 2+3

देखें: https://docs.python.org/2/reference/simple_stmts.html?highlight=print#the-print-statement


पायथन 3.x में, printएक फ़ंक्शन बन जाता है, लेकिन तर्क के sys.stdoutलिए धन्यवाद के अलावा कुछ और पारित करना अभी भी संभव है file

print('Hello', 'World', 2+3, file=open('file.txt', 'w'))

Https://docs.python.org/3/library/functions.html#print देखें


पायथन 2.6+ में, printअभी भी एक बयान है, लेकिन इसे एक फ़ंक्शन के रूप में उपयोग किया जा सकता है

from __future__ import print_function

अपडेट: बकुरीउ ने यह बताने के लिए टिप्पणी की कि प्रिंट फ़ंक्शन और प्रिंट स्टेटमेंट (और आमतौर पर फ़ंक्शन और स्टेटमेंट के बीच अधिक) के बीच एक छोटा सा अंतर है।

तर्कों का मूल्यांकन करते समय एक त्रुटि के मामले में:

print "something", 1/0, "other" #prints only something because 1/0 raise an Exception

print("something", 1/0, "other") #doesn't print anything. The function is not called

64
यह भी ध्यान देने योग्य है कि printजो कुछ भी आप लिखते हैं उसके साथ एक नई रूपरेखा भी जोड़ते हैं sys.stdout.write
माइकल मिओर जूल

5
इसके अलावा sys.stdout.writeअधिक सार्वभौमिक अगर तुम कभी दोहरे संस्करण कोड (जैसे कोड है कि अजगर 2.x के साथ-साथ अजगर 3.x के साथ एक साथ काम करता है) लिखने की ज़रूरत है।
andreb

3
@MichaelMior आप printएक अनुगामी अल्पविराम के साथ print "this",; print "on the same line as this"
जुड़ने

1
@ bjd2385 >>यहाँ संचालक संचालक नहीं है, बल्कि printकथन का एक विशिष्ट "शेवरॉन" रूप है । देखें docs.python.org/2/reference/...
ल्यूक

5
sys.stdout.write()इनपुट को भी बफ़र करता है और हो सकता है कि इनपुट को तुरंत fd पर न बहाएं। यह सुनिश्चित करने के लिए कि यह प्रिंट फ़ंक्शन की तरह व्यवहार करता है, आपको जोड़ना चाहिए: sys.stdout.flush()
kerbelp

151

printपहले ऑब्जेक्ट को स्ट्रिंग में कनवर्ट करता है (यदि यह पहले से ही स्ट्रिंग नहीं है)। यह ऑब्जेक्ट के सामने एक स्थान भी रखेगा यदि यह एक पंक्ति की शुरुआत और अंत में एक नई रेखा चरित्र नहीं है।

उपयोग करते समय stdout , आपको ऑब्जेक्ट को स्वयं एक स्ट्रिंग में बदलने की आवश्यकता है (उदाहरण के लिए, "str" ​​कहकर) और कोई न्यूलाइन वर्ण नहीं है।

इसलिए

print 99

के बराबर है:

import sys
sys.stdout.write(str(99) + '\n')

32
Newline वर्ण का उल्लेख करने के लिए +1! यह मुख्य अंतर है printऔर .write(), मैं कहूंगा।
एरिक ओ लेबिगॉट

9
नोट: printन्यूलाइन को छोड़ना बनाया जा सकता है। पायथन 2.x में, अंत में अल्पविराम लगाएं, और एक अंतरिक्ष वर्ण आउटपुट होगा, लेकिन कोई नई रेखा नहीं। उदा print 99,। पायथन 3 में, print(..., end='')जब तक आप नहीं करते तब तक नई लाइन जोड़ने से बचें (और स्थान जोड़ने से भी बचें end=' '
टूलमेकर

40
@ ईओएल कितना मज़ेदार है, कि EOL नाम का कोई व्यक्ति '\ n' के बारे में टिप्पणी करता है ... इसने मुझे हंसाया। मेरी कोई ज़िदगी नहीं है। मुझे मार डालो।
डेन्डो

2
यह सच नहीं है, printऑपरेशन python2.X में सिग्नल हैंडलर में थोड़ा अलग व्यवहार करता है, अर्थात प्रिंट को sys.stdout से प्रतिस्थापित नहीं किया जा सकता है: उदाहरण में stackoverflow.com/questions/10777610/…
ddzialine

41

मेरा सवाल यह है कि क्या ऐसी परिस्थितियां हैं या नहीं जिनमें sys.stdout.write()बेहतर हो print

दूसरे दिन एक स्क्रिप्ट विकसित करने के बाद, मैंने इसे यूनिक्स सर्वर पर अपलोड कर दिया। मेरे सभी डीबग संदेशों ने printकथन का उपयोग किया, और ये सर्वर लॉग पर दिखाई नहीं देते हैं।

यह एक ऐसा मामला है जहां आपको sys.stdout.writeइसके बजाय आवश्यकता हो सकती है ।


8
है ना? क्या आप सुनिश्चित हैं कि यह print()और के बीच sys.stdout.write()के अंतर के बीच का अंतर है stdoutऔर stderr? डीबगिंग के लिए, आपको loggingमॉड्यूल का उपयोग करना चाहिए , जो संदेशों को प्रिंट करता है stderr
ओस्ट्रोकैच 25'16

1
हां। nohupएक .outफ़ाइल का उपयोग और पुनर्निर्देशन के साथ भी यही सच है ।
coner.xyz

1
sys.stdout.flush () का उपयोग करने में मदद करेगा।
सुप्रीत चौधरी

यदि आप उपयोग करते हैं nohup, तो डिफ़ॉल्ट रूप से सभी लेखन के लिए stdoutऔर stderrफिर से निर्देशित किया जाएगा nohup.out, चाहे आप उपयोग करें printया नहीं stdout.write
झेंग लिउ

40

मार्क लुट्ज़ द्वारा लर्निंग पाइथन की पुस्तक पर आधारित कुछ नमूना कोड यहां दिए गए हैं जो आपके प्रश्न को संबोधित करते हैं:

import sys
temp = sys.stdout                 # store original stdout object for later
sys.stdout = open('log.txt', 'w') # redirect all prints to this log file
print("testing123")               # nothing appears at interactive prompt
print("another line")             # again nothing appears. it's written to log file instead
sys.stdout.close()                # ordinary file object
sys.stdout = temp                 # restore print commands to interactive prompt
print("back to normal")           # this shows up in the interactive prompt

एक पाठ संपादक में log.txt खोलने से निम्नलिखित का पता चलेगा:

testing123
another line

क्या कोई ऐसा तरीका है जिससे मैं स्क्रीन पर लिखने के साथ-साथ फाइल पर लिख सकूं?
देवेश सैनी

5
@DeveshSaini: हाँ, केवल एक वर्ग के साथ sys.stdout को अधिलेखित करें जिसमें कम से कम एक लेखन () और फ्लश () फ़ंक्शन हो। मैंने यहां एक उदाहरण स्निपेट लिखा ।
पोनीकट

14

कम से कम एक स्थिति है जिसमें आप sys.stdoutप्रिंट के बजाय चाहते हैं ।

जब आप अगली पंक्ति पर जाए बिना एक पंक्ति को ओवरराइट करना चाहते हैं, उदाहरण के लिए एक प्रगति बार या स्थिति संदेश को खींचते समय , आपको कुछ इस तरह से लूप करने की आवश्यकता होती है

Note carriage return-> "\rMy Status Message: %s" % progress

और चूंकि प्रिंट एक नई पंक्ति जोड़ता है, आप उपयोग करना बेहतर है sys.stdout


2
यदि प्रिंट एक नई पंक्ति जोड़ता है तो इसके बजाय सिर्फ प्रिंट ('संदेश', अंत = '') ही क्यों?
अपूर्व पटने

8

मेरा सवाल यह है कि क्या ऐसी परिस्थितियां हैं या नहीं जिनमें sys.stdout.write()बेहतर होprint

यदि आप एक कमांड लाइन एप्लिकेशन लिख रहे हैं जो फाइल और स्टडआउट दोनों को लिख सकता है तो यह आसान है। आप निम्न कार्य कर सकते हैं:

def myfunc(outfile=None):
    if outfile is None:
        out = sys.stdout
    else:
        out = open(outfile, 'w')
    try:
        # do some stuff
        out.write(mytext + '\n')
        # ...
    finally:
        if outfile is not None:
            out.close()

इसका मतलब है कि आप with open(outfile, 'w') as out:पैटर्न का उपयोग नहीं कर सकते हैं , लेकिन कभी-कभी यह इसके लायक है।


कड़ाई से बोलते हुए, आप उपयोग कर सकते हैं with- def process(output): # .../ if outfile is None: process(sys.stdout) else: with open(outfile, 'w') as out: process(out)(जहां आवश्यक रूप से नए सिरे जोड़ते हैं)। यह निश्चित रूप से बहुत साफ नहीं है, हालांकि, यह सुनिश्चित करने के लिए है।
निधि मोनिका का मुकदमा

4

2.x में, printस्टेटमेंट आपको जो कुछ भी देता है, उसे प्रीप्रोसेस करता है, उसे रास्ते में घुमाता है, सेपरेटर और न्यूलाइन्स को हैंडल करता है, और एक फाइल पर रीडायरेक्शन की अनुमति देता है। 3.x इसे एक फ़ंक्शन में बदल देता है, लेकिन इसकी अभी भी समान जिम्मेदारियां हैं।

sys.stdout एक फ़ाइल या फ़ाइल-जैसी है जिसमें लिखने के लिए तरीके हैं जो उस रेखा के साथ तार या कुछ लेते हैं।


3

उदाहरण के लिए, जब एक लंबी प्रक्रिया में जानकारी देना उपयोगी हो, तो यह बेहतर है:

import time, sys
Iterations = 555
for k in range(Iterations+1):
    # some code to execute here ...
    percentage = k / Iterations
    time_msg = "\rRunning Progress at {0:.2%} ".format(percentage)
    sys.stdout.write(time_msg)
    sys.stdout.flush()
    time.sleep(0.01)

2
प्रिंट (time_msg, अंत = '') बजाय sys.stdout.write (time_msg) sys.stdout.flush () भी काम करता है
rluts

2
>>> sys.stdout.write(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: expected a string or other character buffer object
>>> sys.stdout.write("a")
a>>> sys.stdout.write("a") ; print(1)
a1

उपरोक्त उदाहरण का अवलोकन करना:

  1. sys.stdout.writeगैर-स्ट्रिंग ऑब्जेक्ट नहीं लिखेंगे, लेकिन printकरेंगे

  2. sys.stdout.writeअंत में एक नई लाइन प्रतीक नहीं जोड़ेंगे, लेकिन printहोगा

यदि हम गहराई से गोता लगाते हैं,

sys.stdout एक फाइल ऑब्जेक्ट है जो प्रिंट के आउटपुट के लिए इस्तेमाल किया जा सकता है ()

यदि फ़ाइल का तर्क print()निर्दिष्ट नहीं है, sys.stdoutतो इसका उपयोग किया जाएगा


1

क्या ऐसी स्थितियाँ हैं जिनमें sys.stdout.write () प्रिंट करना बेहतर है?

उदाहरण के लिए, मैं छोटे फ़ंक्शन पर काम कर रहा हूं, जो संख्या को तर्क के रूप में पास करने पर पिरामिड प्रारूप में सितारों को प्रिंट करता है, हालांकि आप इसे एक अलग लाइन में प्रिंट करने के लिए = "" का उपयोग करके पूरा कर सकते हैं , मैंने समन्वय में sys.stdout.write का उपयोग किया इस काम को करने के लिए प्रिंट के साथ । इस stdout.write प्रिंट को उसी लाइन में विस्तृत करने के लिए जहां प्रिंट हमेशा एक अलग लाइन में अपनी सामग्री प्रिंट करता है।

import sys

def printstars(count):

    if count >= 1:
        i = 1
        while (i <= count):
            x=0
            while(x<i):
                sys.stdout.write('*')
                x = x+1
            print('')
            i=i+1

printstars(5)

1

क्या ऐसी स्थितियाँ हैं जिनमें sys.stdout.write () प्रिंट करना बेहतर है?

मैंने पाया है कि मल्टीथ्रेडिंग स्थिति में प्रिंट की तुलना में स्टडआउट बेहतर काम करता है। मैं मुद्रण के लिए लाइनों को संग्रहीत करने के लिए कतार (FIFO) का उपयोग करता हूं और जब तक मेरा प्रिंट Q रिक्त नहीं होता है तब तक मैं प्रिंट लाइन से पहले सभी थ्रेड रखता हूं। फिर भी, प्रिंट का उपयोग करते हुए मैं कभी-कभी डिबग I / O (विंग प्रो आईडीई का उपयोग करके) पर अंतिम \ n खो देता हूं।

जब मैं स्ट्रिंग में \ n के साथ std.out का उपयोग करता हूं तो डिबग I / O प्रारूप सही ढंग से और \ n के सही प्रदर्शित होते हैं।


क्या आप किसी भी कारण से जानते हैं कि इस मामले में प्रिंट से बेहतर काम क्यों करना चाहिए, या क्या यह किस्सा है? क्या आप एक न्यूनतम कार्य उदाहरण प्रदान कर सकते हैं जहां ऐसा होता है?
user2653663 8

मेरी सोच यह है कि प्रिंट की तुलना में स्टडआउट निचले स्तर पर काम करता है। मुझे निश्चित रूप से धागा भ्रष्टाचार था क्योंकि दो प्रिंट रूटीन स्टडआउट के माध्यम से खिलाने के लिए लड़ रहे थे। प्रत्येक सूत्र से एक को हटाने के लिए लिखने से मेरे लिए भ्रष्टाचार दूर हो गया।
डेविड पाउंडल


1

पायथन 3 में प्रिंट ओवर का उपयोग करने का वैध कारण है sys.stdout.write, लेकिन इस कारण को भी उपयोग करने के लिए एक कारण में बदल दिया जा सकता हैsys.stdout.write

यह कारण है कि, अब प्रिंट पायथन 3 में एक फ़ंक्शन है, आप इसे ओवरराइड कर सकते हैं। इसलिए आप एक साधारण स्क्रिप्ट में हर जगह प्रिंट का उपयोग कर सकते हैं और तय कर सकते हैं कि प्रिंट स्टेटमेंट को stderrइसके बजाय लिखने की जरूरत है। अब आप केवल प्रिंट फ़ंक्शन को फिर से परिभाषित कर सकते हैं, आप प्रिंट फ़ंक्शन को ग्लोबल भी बदल सकते हैं इसे बिलिंस मॉड्यूल का उपयोग करके बदल सकते हैं। के साथ बेशकfile.writeआपके निर्दिष्ट कर सकते हैं कि फ़ाइल क्या है, लेकिन ओवरराइटिंग प्रिंट के साथ आप लाइन विभाजक, या तर्क विभाजक को फिर से परिभाषित कर सकते हैं।

चारों ओर दूसरा रास्ता है। हो सकता है कि आप पूरी तरह से निश्चित हैं कि आप लिखते हैं stdout, लेकिन यह भी जानते हैं कि आप प्रिंट को किसी और चीज़ में बदलने जा रहे हैं, आप उपयोग करने का निर्णय ले सकते हैंsys.stdout.write , और त्रुटि लॉग या कुछ और के लिए प्रिंट ।

इसलिए, आप जो उपयोग करते हैं वह इस बात पर निर्भर करता है कि आप इसका उपयोग कैसे करना चाहते हैं। printअधिक लचीला है, लेकिन इसका उपयोग करने और इसका उपयोग न करने का एक कारण हो सकता है। मैं अब भी लचीलेपन का विकल्प चुनूंगा, और प्रिंट चुनूंगा। printइसके बजाय उपयोग करने का एक और कारण परिचित है। अधिक लोगों को अब आप प्रिंट और कम पता से क्या मतलब होगा sys.stdout.write


1

अंतर में से एक निम्नलिखित है, जब एक बाइट को उसके हेक्साडेसिमल उपस्थिति में प्रिंट करने की कोशिश कर रहा है। उदाहरण के लिए, हम चाहते हैं कि दशमलव मान पता की 255है 0xFFहेक्साडेसिमल दिखने में:

val = '{:02x}'.format(255) 

sys.stdout.write(val) # prints ff2
print(val)            # prints ff

यह इस बारे में नहीं है। यह केवल एक इंटरैक्टिव शेल में होता है और क्योंकि ... write()जोड़ा नहीं जाता है \nऔर (और इंटरेक्टिव शेल डिस्प्ले) फ़ंक्शन के रिटर्न वैल्यू (लिखे गए वर्णों की संख्या), हेक्साडेसिमल प्रतिनिधित्व या प्रदर्शित होने वाली कोई अन्य सामग्री सारहीन है।
ओद्रेज के।

0

अजगर 2 में यदि आपको किसी फ़ंक्शन के आसपास से गुजरने की आवश्यकता होती है तो आप os.sys.stdout.write को एक चर में निर्दिष्ट कर सकते हैं, आप प्रिंट के साथ ऐसा नहीं कर सकते (उत्तर में)।

>import os
>>> cmd=os.sys.stdout.write
>>> cmd('hello')
hello>>> 

जो उम्मीद के मुताबिक काम करता है।

>>> cmd=print
  File "<stdin>", line 1
    cmd=print
            ^
SyntaxError: invalid syntax

वह काम नहीं करता। प्रिंट एक जादुई कार्य है।


0

Python 3 में इंगित करने के लिए printऔर इसके बीच का अंतर sys.stdout.write, टर्मिनल में निष्पादित होने पर लौटाया जाने वाला मान भी है। पाइथन 3 sys.stdout.writeमें स्ट्रिंग का लेन printलौटाता है जबकि रिटर्न सिर्फNone

इसलिए उदाहरण के लिए टर्मिनल में कोड को अंतःक्रियात्मक रूप से चलाने के बाद स्ट्रिंग को प्रिंट किया जाएगा, इसके बाद लेन को लौटाया जाएगा, क्योंकि लेन-देन को लौटाया जाता है और अंतःक्रियात्मक रूप से चलाने पर आउटपुट किया जाता है:

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