it-swarm.com.de

Wie drucke ich in Python auf stderr?

Es gibt verschiedene Möglichkeiten, an stderr zu schreiben:

# Note: this first one does not work in Python 3
print >> sys.stderr, "spam"

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

os.write(2, b"spam\n")

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

Das scheint zu widersprechen Zen von Python # 1 Was ist hier der Unterschied und gibt es Vor- oder Nachteile in der einen oder anderen Richtung? Welcher Weg soll benutzt werden?

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

1185
wim

Ich fand dies die einzige kurze + flexible + tragbare + lesbare:

from __future__ import print_function
import sys

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

Die Funktion eprint kann wie die Standardfunktion print verwendet werden:

>>> print("Test")
Test
>>> eprint("Test")
Test
>>> eprint("foo", "bar", "baz", sep="---")
foo---bar---baz
1026
MarcH
import sys
sys.stderr.write()

Ist meine Wahl, nur lesbarer und genau das, was Sie tun wollen und portabel über Versionen.

Bearbeiten: 'Pythonic' zu sein, ist für mich ein dritter Gedanke in Bezug auf Lesbarkeit und Leistung. Unter Berücksichtigung dieser beiden Aspekte werden python 80% Ihres Codes Pythonic sein. Listenverständnis ist das "große Ding", das nicht so oft verwendet wird (Lesbarkeit).

496
Mike Ramirez

Für Python 2 habe ich folgende Wahl: print >> sys.stderr, 'spam' Da Sie Listen/Dikte usw. einfach drucken können, ohne sie in einen String umzuwandeln. print >> sys.stderr, {'spam': 'spam'} anstelle von: sys.stderr.write(str({'spam': 'spam'}))

130

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)

Für viele von uns ist es etwas unnatürlich, das Ziel auf das Ende des Befehls zu verweisen. Die Alternative

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

sieht objektorientierter aus und geht elegant vom Allgemeinen zum Besonderen über. Beachten Sie jedoch, dass write kein 1: 1-Ersatz für print ist.

126
Joachim W

Bisher hat noch niemand logging erwähnt, aber die Protokollierung wurde speziell für die Übermittlung von Fehlermeldungen erstellt. Standardmäßig ist es so eingestellt, dass in stderr geschrieben wird. Dieses Skript:

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

logging.warning('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')

(Beachten Sie, dass logging.warnveraltet war, verwenden Sie stattdessen logging.warning)

94
slushy

Ich würde sagen, dass Ihr erster Ansatz:

print >> sys.stderr, 'spam' 

ist der "Eine ... offensichtliche Weg, es zu tun" Die anderen erfüllen die Regel # 1 nicht ("Schön ist besser als hässlich.")

32
Carl F.

Ich habe folgendes mit Python 3 gemacht:

from sys import stderr

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

So kann ich jetzt beispielsweise Schlüsselwortargumente hinzufügen, um Wagenrücklauf zu vermeiden:

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

Dies ahmt die Standarddruckfunktion nach, gibt sie jedoch auf stderr aus

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

EDIT Im Nachhinein denke ich, dass die mögliche Verwechslung mit dem Ändern von sys.stderr und dem Nicht-Sehen des aktualisierten Verhaltens diese Antwort nicht so gut wie gerecht macht Verwenden einer einfachen Funktion, wie andere darauf hingewiesen haben.

Wenn Sie nur teilweise verwenden, sparen Sie 1 Codezeile. Die mögliche Verwirrung ist es nicht wert, eine Codezeile zu sparen.

Original

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

from __future__ import print_function
import sys
from functools import partial

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

Du benutzt es dann so

error('An error occured!')

Sie können überprüfen, ob auf stderr und nicht stdout gedruckt wird, indem Sie den folgenden (überschreibenden Code aus http://coreygoldberg.blogspot.com.au/2009/05/python-redirect-or-turn-off) ausführen -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 hierbei ist, dass der Wert von sys.stderr der umschlossenen Funktion zum Zeitpunkt der Erstellung teilweise zugewiesen wird . Dies bedeutet, dass , wenn Sie stderr später umleiten, diese Funktion nicht beeinträchtigt wird. Wenn Sie stderr umleiten möchten, verwenden Sie die von angegebene ** kwargs-Methode aaguirre auf dieser Seite.

17
Rebs

In Python 3 kann man einfach print (): verwenden

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

fast aus der Schachtel:

import sys
print("Hello, world!", file=sys.stderr)

oder:

from sys import stderr
print("Hello, world!", file=stderr)

Dies ist unkompliziert und muss nur sys.stderr enthalten.

9

Gleiches gilt für stdout:

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

Wie in den anderen Antworten angegeben, bietet print eine hübsche Oberfläche, die häufig praktischer ist (z. B. zum Drucken von Debug-Informationen), während write schneller ist und auch praktischer sein kann, wenn Sie müssen die Ausgabe genau auf bestimmte Weise formatieren. Ich würde auch die Wartbarkeit berücksichtigen:

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

  2. print () Die Syntax wurde in Python 3 geändert. Wenn Sie also beide Versionen unterstützen müssen, ist write () möglicherweise besser.

7
Seppo Enarvi

Ich arbeite in python 3.4.3. Ich schneide eine kleine Eingabe aus, die zeigt, wie ich hierher gekommen bin:

[18:19 [email protected] pexpect]$ python3
>>> import sys
>>> print("testing", file=sys.stderr)
testing
>>>
[18:19 [email protected] pexpect]$ 

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

[18:22 [email protected] pexpect]$ python3 2> /tmp/test.txt
>>> import sys
>>> print("testing", file=sys.stderr)
>>> [18:22 [email protected] pexpect]$
[18:22 [email protected] 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 [email protected] pexpect]$

Abgesehen von der Tatsache, dass die kleine Einführung, die python Ihnen gibt, in stderr geschlürft wurde (wohin würde es sonst gehen?), Funktioniert es.

6
user1928764

Wenn Sie einen einfachen Test machen:

import time
import sys

def run1(runs):
    x = 0
    cur = time.time()
    while x < runs:
        x += 1
        print >> sys.stderr, 'X'
    elapsed = (time.time()-cur)
    return elapsed

def run2(runs):
    x = 0
    cur = time.time()
    while x < runs:
        x += 1
        sys.stderr.write('X\n')
        sys.stderr.flush()
    elapsed = (time.time()-cur)
    return elapsed

def compare(runs):
    sum1, sum2 = 0, 0
    x = 0
    while x < runs:
        x += 1
        sum1 += run1(runs)
        sum2 += run2(runs)
    return sum1, sum2

if __== '__main__':
    s1, s2 = compare(1000)
    print "Using (print >> sys.stderr, 'X'): %s" %(s1)
    print "Using (sys.stderr.write('X'),sys.stderr.flush()):%s" %(s2)
    print "Ratio: %f" %(float(s1) / float(s2))

Sie werden feststellen, dass sys.stderr.write () durchgehend 1,81 mal schneller ist!

3
ThePracticalOne

Die Antwort auf die Frage lautet: Es gibt verschiedene Möglichkeiten, stderr in python zu drucken, aber das hängt davon ab, 1.) welche python-Version wir verwenden 2.) welche Ausgabe wir genau wollen.

Der Unterschied zwischen der Schreibfunktion von print und stderr: stderr: stderr (Standardfehler) ist eine Pipe, die in jedes UNIX/Linux-System integriert ist, wenn Ihr Programm abstürzt und Debugging-Informationen ausgibt (wie ein Traceback in Python) ) geht es zum stderr rohr.

print: print ist ein Wrapper, der die Eingaben formatiert (die Eingabe ist der Abstand zwischen dem Argument und dem Zeilenumbruch am Ende) und dann die Schreibfunktion eines bestimmten Objekts aufruft, das angegebene Objekt ist standardmäßig sys.stdout, aber wir können eine Datei übergeben, dh wir können die Eingabe auch in einer Datei drucken.

Python2: Wenn wir dann Python2 verwenden

>>> import sys
>>> print "hi"
hi
>>> print("hi")
hi
>>> print >> sys.stderr.write("hi")
hi

Das nachgestellte Python2-Komma ist in Python3 zu einem Parameter geworden. Wenn wir also nach dem Drucken nachgestellte Kommas verwenden, um die Zeilenumbrüche zu vermeiden, sieht dies in Python3 wie print ('Text to print', end = '') aus, was unter Python2 ein Syntaxfehler ist .

http://python3porting.com/noconv.html

Wenn wir dasselbe über sceario in python3 überprüfen:

>>> import sys
>>> print("hi")
hi

Unter Python 2.6 gibt es einen future -Import, um Ausdrucke in eine Funktion zu machen. Um Syntaxfehler und andere Unterschiede zu vermeiden, sollten wir alle Dateien, in denen print () verwendet wird, mit from future import print_function starten. Der future -Import funktioniert nur unter Python 2.6 und höher, sodass Sie für Python 2.5 und früher zwei Optionen haben. Sie können entweder den komplexeren Ausdruck in einen einfacheren umwandeln oder eine separate Druckfunktion verwenden, die sowohl unter Python2 als auch unter Python3 funktioniert.

>>> from __future__ import print_function
>>> 
>>> def printex(*args, **kwargs):
...     print(*args, file=sys.stderr, **kwargs)
... 
>>> printex("hii")
hii
>>>

Fall: Beachten Sie, dass sys.stderr.write () oder sys.stdout.write () (stdout (Standardausgabe) eine Pipe ist, die in jedes UNIX/Linux-System integriert ist) kein Ersatz für print ist, aber ja wir können es in einigen Fällen als Alternative verwenden. Print ist ein Wrapper, der die Eingabe am Ende mit Leerzeichen und Zeilenumbruch umschließt und die Write-Funktion zum Schreiben verwendet. Dies ist der Grund, warum sys.stderr.write () schneller ist.

Hinweis: Wir können auch mithilfe der Protokollierung nachverfolgen und Fehler beheben

#test.py
import logging
logging.info('This is the existing protocol.')
FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s"
logging.basicConfig(format=FORMAT)
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning("Protocol problem: %s", "connection reset", extra=d)

https://docs.python.org/2/library/logging.html#logger-objects

0
Vinay Kumar

Versuchen:

from sys import stderr


print >> sys.stderr, 'spam' 
0
Leon pvc