2010-07-16 13 views
236

Ci sono situazioni in cui sys.stdout.write() è preferibile a print?La differenza tra sys.stdout.write e stampa?

(Esempi: un miglior rendimento; codice che ha più senso)

+4

Quale versione di Python? 2.xo 3.x? –

+0

Onestamente mi piacerebbe sapere per entrambi, anche se non ho esperienza con Python 3. Aggiornato la domanda. –

+9

@ S.Lott: chiedere le differenze di base tra 'sys.stdout.write()' e 'print' (e/o perché Python ha entrambi) è una domanda perfettamente ragionevole e non ha bisogno di esempi. OP non ha detto che la sintassi del comando era confusa. – smci

risposta

197

print è solo un involucro sottile che formatta gli ingressi (spazio tra args e newline alla fine) e chiede la funzione di scrittura di un oggetto dato. Per impostazione predefinita, questo oggetto è sys.stdout, ma è possibile passare un file utilizzando il modulo "chevron". Per esempio:

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

See: https://docs.python.org/2/reference/simple_stmts.html?highlight=print#the-print-statement


In Python 3.x, print diventa una funzione, ma è ancora possibile passare qualcosa di diverso sys.stdout grazie alla tesi file.

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

Vedi https://docs.python.org/3/library/functions.html#print


In Python 2.6+, print è ancora una dichiarazione, ma può essere utilizzato come una funzione con

from __future__ import print_function 

Update: Non c'è una piccola differenza tra la funzione di stampa e l'istruzione di stampa (e più in generale tra una funzione e come Tatuaggio) indicato da Bakuriu nei commenti.

In caso di errore durante il rilevamento argomenti

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

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

Vale anche la pena notare che ' print' aggiunge anche una nuova riga a qualsiasi cosa tu scriva, cosa che non succede con 'sys.stdout.write'. –

+0

@ Michael Mior: Vero, ho detto che" formatta gli input ". Una migliore risposta direbbe che tipo di formattazione Grazie per il chiarimento – luc

+0

Anche 'sys.stdout.write' è più universale se hai mai bisogno di scrivere dual-versi sul codice (ad es. codice che funziona contemporaneamente con Python 2.x e con Python 3.x). – andreb

2

In 2.x, la dichiarazione print preprocessa ciò che si dà, trasformandolo in stringhe lungo la strada, la manipolazione separatori e ritorni a capo, e consentendo il reindirizzamento a un file. 3.x lo trasforma in una funzione, ma ha ancora le stesse responsabilità.

sys.stdout è un file o un file che ha metodi per scrivervi, che accettano stringhe o qualcosa lungo quella linea.

98

"print" converte prima l'oggetto in una stringa (se non è già una stringa). Metterà anche uno spazio davanti all'oggetto se non è l'inizio di una linea e un carattere di fine riga alla fine.

Quando si utilizza lo stdout, è necessario convertire l'oggetto in una stringa da soli (chiamando "str", ad esempio) e non vi è alcun carattere di fine riga.

Così

print 99 

è equivalente a:

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

+1 per menzionare il carattere di nuova riga! Questa è la principale differenza tra 'print' e' .write() ', direi. – EOL

+7

NOTA: 'stampa' può essere fatto per omettere la nuova riga. In Python 2.x, inserisci una virgola alla fine e verrà visualizzato un carattere di spazio, ma non una nuova riga. Per esempio. 'print 99,' In Python 3, 'print (..., end = '')' eviterà l'aggiunta di newline (ed eviterà anche di aggiungere spazio, a meno che non si usi 'end = ''. – ToolmakerSteve

+16

@EOL Quanto è divertente che , che qualcuno di nome EOL fa un commento su '\ n' ... Mi ha fatto ridere Non ho vita Mi uccidi – Depado

30

mia domanda è se o non vi sono situazioni in cui sys.stdout.write() è preferibile print

dopo aver terminato lo sviluppo di un script l'altro giorno, l'ho caricato su un server unix. Tutti i miei messaggi di debug hanno utilizzato le istruzioni print e questi non vengono visualizzati in un registro del server.

Questo è un caso in cui potrebbe essere necessario sys.stdout.write invece.

+1

eh? Sei sicuro che questa sia una differenza tra 'print()' e 'sys.stdout.write()', al contrario della differenza tra 'stdout' e' stderr'? Per il debug, dovresti usare il modulo 'logging', che stampa i messaggi su' stderr'. – ostrokach

+0

Ya. Lo stesso vale per l'uso di 'nohup' e il reindirizzamento a un file' .out'. –

23

Ecco alcuni esempi di codice basato sul libro Learning Python da Mark Lutz che si rivolge alla tua domanda:

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 

Apertura log.txt in un editor di testo rivelerà il seguente:

testing123 
another line 
+0

Esiste un modo per poter stampare sullo schermo e scrivere sul file? –

+3

@DeveshSaini: Sì, basta sovrascrivere sys.stdout con una classe proxy che abbia almeno una funzione write() e flush(). Ho scritto uno snippet di esempio [qui] (http://hastebin.com/owijihizus.py). – ponycat

8

La mia domanda è se ci sono o meno situazioni in cui sys.stdout.write() è preferibile a print

Se si sta scrivendo un'applicazione da riga di comando in grado di scrivere su entrambi i file e sullo stdout, è utile. Si può fare cose come:

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() 

vuol dire non è possibile utilizzare il modello with open(outfile, 'w') as out:, ma a volte ne vale la pena.

5

C'è almeno una situazione in cui si desidera sys.stdout anziché stampare.

Quando si desidera sovrascrivere una linea senza andare alla riga successiva, per esempio mentre si disegna una barra di avanzamento o di un messaggio di stato, è necessario un ciclo su qualcosa come

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

E poiché di stampa aggiunge una nuova riga, è meglio usare sys.stdout.

0

Esistono situazioni in cui sys.stdout.write() è preferibile alla stampa ?

Per esempio sto lavorando su piccola funzione che consente di stampare in formato stelle piramide previo superamento del numero come argomento, anche se è possibile ottenere questo risultato utilizzando end = "" per stampare in una riga separata, ho utilizzato sys.stdout.write in coordinamento con stampa per fare questo lavoro. Per elaborare questo stdout .scrivi stampe nella stessa riga dove stampa stampa sempre i suoi contenuti in una riga separata.

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)