stdout in datei

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Sync32
User
Beiträge: 141
Registriert: Mittwoch 27. Januar 2010, 12:42

Wie bekomme ich die kompletten Konsolausgabe von meinem Python program?
Ich möchte diese in einer Datei speichern.

Hab zwar ne Möglichkeit gefunden:

Code: Alles auswählen

import sys
print 'Dive in'                                          
saveout = sys.stdout                                     
fsock = open('out.log', 'w')                             
sys.stdout = fsock                                       
print 'This message will be logged instead of displayed' 
sys.stdout = saveout                                     
fsock.close()  
aber da lenke ich das stdout nur um. Die normalen Prints werden denn nicht mehr in der Konsole angezeigt.

Ich möchte, das die Ausgaben weiterhin in der Konsole gemacht werden und zusätzlich diese in einer Datei speichern
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Suchst du vielleicht das logging-Modul?

Sebastian
Das Leben ist wie ein Tennisball.
fsck
User
Beiträge: 5
Registriert: Dienstag 4. Januar 2011, 22:13

Code: Alles auswählen

import sys

class MyOut(object):
    def __init__(self, streams):
        self.streams = streams

    def write(self, data):
        for stream in self.streams:
            stream.write(data)

file = open('out.log', 'w')
sys.stdout = MyOut([file, sys.stdout])

print 'foo'
Sync32
User
Beiträge: 141
Registriert: Mittwoch 27. Januar 2010, 12:42

ok der code funktioniert, versteh ihn aber nicht ganz

wann setzt er write ein? und woher bekommt er data?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Sync32 hat geschrieben:ok der code funktioniert, versteh ihn aber nicht ganz

wann setzt er write ein? und woher bekommt er data?
Der Code ist in einigen Teilen auch sehr unschön ;-) `file` sollte man nicht überschreiben, da das ein Built-in Name ist.

Grundsätzlich ist das eine Art Monkey-Patching. fsck baut ein Objekt, welches eine `write`-Methode besitzt. Intern ruft Python augenscheinlich beim `print`-Statement die `write`-Methode eines Objektes auf, welches sich an den Namen `sys.stdout` gebunden ist. Dieses Objekt gibt damit dann den String an die Shell weiter. fsck schaltet sich also quasi dazwischen, indem er ganz Duck Typing konform ein Objekt dazwischen schaltet. Dieses Objekt ruft nun aber eben nicht nur die `write`-Methode von `sys.stdout` auf, sondern alle von einer Liste von `file`-like Objekten. Er bindet dieses neue Objekt einfach an `sys.stdout` und übergibt ihm neben dem alten Objekt hinter `sys.stdout` zusätzlich ein (Log-)Datei-Objekt. Intern ruft Python nun also das neue Objekt hinter `sys.stdout` auf und landet damit in der `write`-Methode von `MyOut`.

Generell sollte man Dateien aber immer schließen - das passiert hier nicht ;-) Zudem ist der ganze Ansatz immer noch in Frage zu stellen, wo es doch spezielle Logging-Module gibt.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Sync32
User
Beiträge: 141
Registriert: Mittwoch 27. Januar 2010, 12:42

Danke für diese ausführliche Erklärung.

Beim Dateihandling hat er mir nun aber manchmal

AttributeError: MyOut instance has no attribute 'flush'

ausgespuckt. Wie sollte man die am besten überschreiben?
BlackJack

@Sync32: Na genau wie beim `write()` — einfach weiter reichen den Aufruf.
Antworten