Frage Wie drucke ich in Python 2 nach stderr?


Ich habe mindestens drei Möglichkeiten gefunden, um auf stderr zu drucken:

 import sys

 print >> sys.stderr, 'spam'

 sys.stderr.write('spam\n')

 from __future__ import print_function
 print('spam', file=sys.stderr)

Es scheint zu widersprechen Zen von Python # 13  Was ist der bevorzugte Weg, um es zu tun? Gibt es Vorteile oder Nachteile auf die eine oder andere Art?

  Es sollte einen - und vorzugsweise nur einen - offensichtlichen Weg geben, dies zu tun.


988
2018-04-07 00:59


Ursprung


Antworten:


Ich fand, dass dies die einzige kurze + flexible + portable + lesbare ist:

from __future__ import print_function
import sys

def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

Die Funktion eprint kann auf die gleiche Weise wie der Standard verwendet werden print Funktion:

>>> print("Test")
Test
>>> eprint("Test")
Test
>>> eprint("foo", "bar", "baz", sep="---")
foo---bar---baz

845
2018-02-20 13:31



sys.stderr.write() ist meine Wahl, nur besser lesbar und genau zu sagen, was Sie beabsichtigen zu tun und portabel über Versionen.

Edit: pythisch zu sein ist für mich ein dritter Gedanke über Lesbarkeit und Performance ... mit diesen zwei Dingen im Hinterkopf, mit Python werden 80% Ihres Codes pythonisch sein. Listenverständnis ist das "große Ding", das nicht so oft benutzt wird (Lesbarkeit).


399
2018-04-07 01:03



Zum Python 2 meine Wahl ist: print >> sys.stderr, 'spam' Weil Sie Listen / Diktate einfach ausdrucken können, ohne sie in eine Zeichenkette umzuwandeln. print >> sys.stderr, {'spam': 'spam'} Anstatt von: sys.stderr.write(str({'spam': 'spam'}))


120
2017-11-08 17:29



print >> sys.stderr ist in Python3 verschwunden. http://docs.python.org/3.0/whatsnew/3.0.html sagt:

Old: print >>sys.stderr, "fatal error"
New: print("fatal error", file=sys.stderr)

Leider ist das ziemlich hässlich. Alternativ, verwenden Sie

sys.stderr.write("fatal error\n")

aber beachte das write ist kein 1: 1 Ersatz für print.


97
2018-04-04 10:00



Niemand wird erwähnt logging noch, aber Protokollierung wurde speziell zur Kommunikation von Fehlermeldungen erstellt. Standardmäßig ist es so eingestellt, dass es in stderr schreibt. Dieses Skript:

# foo.py
import logging
logging.basicConfig(format='%(message)s')

logging.warn('I print to stderr by default')
logging.info('For this you must change the level and add a handler.')
print('hello world')

hat das folgende Ergebnis, wenn es in der Befehlszeile ausgeführt wird:

$ python3 foo.py > bar.txt
I print to stderr by default

(und bar.txt enthält die "Hallo Welt")


52
2017-12-23 16:04



Ich würde sagen, dass dein erster Ansatz:

print >> sys.stderr, 'spam' 

ist der eine . . . offensichtlich Art und Weise es zu tun "Die anderen genügen Regel 1 nicht (" Schön ist besser als hässlich. ")


32
2018-04-07 01:05



Ich habe folgendes mit Python 3 gemacht:

from sys import stderr

def print_err(*args, **kwargs):
    print(*args, file=stderr, **kwargs)

Jetzt kann ich beispielsweise Schlüsselwortargumente hinzufügen, um eine Wagenrückkehr zu vermeiden:

print_err("Error: end of the file reached. The word ", end='')
print_err(word, "was not found")

28
2017-12-29 21:40



Dies wird die Standarddruckfunktion nachahmen, aber auf stderr ausgeben

def print_err(*args):
    sys.stderr.write(' '.join(map(str,args)) + '\n')

18
2017-10-06 07:42



BEARBEITEN Im Nachhinein denke ich, dass die mögliche Verwechslung mit dem Ändern von sys.stderr und nicht das Aktualisieren des Verhaltens aktualisiert diese Antwort nicht so gut macht, als nur eine einfache Funktion zu verwenden, wie andere darauf hingewiesen haben.

Wenn Sie nur partiell verwenden, werden nur 1 Codezeile gespeichert. Die mögliche Verwirrung ist es nicht wert, 1 Codezeile zu speichern.

Original

Um es noch einfacher zu machen, hier ist eine Version, die "teilweise" verwendet, was eine große Hilfe bei den Umbruchfunktionen ist.

from __future__ import print_function
import sys
from functools import partial

error = partial(print, file=sys.stderr)

Sie benutzen es dann so

error('An error occured!')

Sie können überprüfen, ob es auf stderr und nicht auf stdout gedruckt wird, indem Sie Folgendes tun (Code überschreiben von http://coreygoldberg.blogspot.com.au/2009/05/python-redirect-or-turn-off-stdout-and.html):

# over-ride stderr to prove that this function works.
class NullDevice():
    def write(self, s):
        pass
sys.stderr = NullDevice()

# we must import print error AFTER we've removed the null device because
# it has been assigned and will not be re-evaluated.
# assume error function is in print_error.py
from print_error import error

# no message should be printed
error("You won't see this error!")

Der Nachteil ist teilweise vergibt der Wert von sys.stderr für die umbrochene Funktion zum Zeitpunkt der Erstellung. Was bedeutet, Wenn Sie stderr später umleiten, hat dies keine Auswirkungen auf diese Funktion. Wenn Sie stderr umleiten möchten, verwenden Sie die von mir erwähnte Methode ** kwargs Aaguirre auf dieser Seite.


16
2017-12-30 02:13



Gleiches gilt für stdout:

print 'spam'
sys.stdout.write('spam\n')

Wie in den anderen Antworten angegeben, drucken bietet eine hübsche Schnittstelle, die oft bequemer ist (z. B. zum Drucken von Debug-Informationen), während schreiben ist schneller und kann auch bequemer sein, wenn Sie die Ausgabe genau auf bestimmte Weise formatieren müssen. Ich würde auch Wartbarkeit in Betracht ziehen:

  1. Sie können später entscheiden, zwischen stdout / stderr und einer regulären Datei zu wechseln.

  2. drucken() Syntax hat sich in Python 3 geändert, wenn Sie also beide Versionen unterstützen müssen, schreiben() könnte besser sein.


6
2017-11-01 11:58



Ich arbeite in Python 3.4.3. Ich schneide ein bisschen Tippen aus, das zeigt, wie ich hierher gekommen bin:

[18:19 jsilverman@JSILVERMAN-LT7 pexpect]$ python3
>>> import sys
>>> print("testing", file=sys.stderr)
testing
>>>
[18:19 jsilverman@JSILVERMAN-LT7 pexpect]$ 

Hat es funktioniert? Versuchen Sie stderr in eine Datei umzuleiten und sehen Sie, was passiert:

[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$ python3 2> /tmp/test.txt
>>> import sys
>>> print("testing", file=sys.stderr)
>>> [18:22 jsilverman@JSILVERMAN-LT7 pexpect]$
[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$ cat /tmp/test.txt
Python 3.4.3 (default, May  5 2015, 17:58:45)
[GCC 4.9.2] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
testing

[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$

Nun, abgesehen von der Tatsache, dass die kleine Einleitung, die Python Ihnen gibt, in stderr (wo sonst würde es gehen?) Geschlürft wird, funktioniert es.


4
2018-02-10 02:29