Hallo liebes Forum,
ich bin ein Python-Neuling und würde gerne wissen, ob es eine elegante Methode gibt, z.B. einen String gleichzeitig auf dem Bildschirm und in eine Datei auszugeben.
Ich muss nämlich ein Skript schreiben, bei dem alle Programmschritte in einer Logfile dokumentiert und teilweise zusätzlich auf dem Bildschirm ausgegeben werden müssen.
Gruß
ArtS
Gleichzeitige Ausgabe auf Bildschirm und Datei
Ein unelegante Methode wäre meiner Meinung nach, den String erst mit dem Print-Befehl auf dem Bildschirm auszugeben und dann den gleichen String nochmal mit der write-Methode in die Datei zu schreiben.
Es sind wirklich viele Strings, die ich so verarbeiten müsste.
Es sind wirklich viele Strings, die ich so verarbeiten müsste.
Oder durch Umleiten des stdouts an eine eigene Klasse, die dann diese Aufgabe erledigt. Dann kann ganz normal das print Statement für die Ausgaben verwendet werden:
http://paste.pocoo.org/show/130246/
http://paste.pocoo.org/show/130246/
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Das hat diverse Probleme, angefangen vom Schreiben auf sys.__stdout__, darüber, dass sinnlose Newlines an text angehängt werden und willkürliche Werte von "text" ausgeschlossen werden, bis hin dazu dass es recht ineffizient ist, die Datei bei jedem write() *dreimal* aufzumachen und wieder zu schließen.ice2k3 hat geschrieben:Oder durch Umleiten des stdouts an eine eigene Klasse, die dann diese Aufgabe erledigt. Dann kann ganz normal das print Statement für die Ausgaben verwendet werden:
http://paste.pocoo.org/show/130246/
Bei jedem 1000 Mal wird die Datei 3-Mal geöffnet...
Außerdem ist das natürlich spezifisch an meine Anforderungen angepasst. Für ihn müsste er es halt noch modifizieren.
Außerdem wird bei dem normalen stdout auch eine newline angehängt.
Und was ist das Problem mit dem Schreiben auf sys.__stdout__ ?
Außerdem ist das natürlich spezifisch an meine Anforderungen angepasst. Für ihn müsste er es halt noch modifizieren.
Außerdem wird bei dem normalen stdout auch eine newline angehängt.
Und was ist das Problem mit dem Schreiben auf sys.__stdout__ ?
@ice2k3: `__stdout__` ist "magisch". Das sollte immer an das original `__stdout__` vom Start des Python-Interpretierers gebunden sein. Warum verwendest Du da nicht einfach `sys.stdout`? Das ist die offizielle API die man verwenden sollte.
@ice2k3: Ich habe in den Quelltext geschaut und sehe nicht, warum Du nicht das "originale" `sys.stdout` verwendest. Es ist ja nicht sichergestellt, dass vor Deinem Code ``sys.stdout == `sys.__stdout__`` gilt. Kann ja zum Beispiel auch sein, dass es sich um eine GUI-Anwendung handelt, die vorher schon `sys.stdout` auf ein Objekt umgebogen hat, dass die Ausgaben in einem Textfenster anzeigt. Dann biegst Du die Ausgaben mit Deinem Logger aus Sicht des Anwenders ins Nirwana um.
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Stimmt, das hab ich falsch interpretiert. Da fällt mir noch auf: `line_count` ist verwirrend, weil write() generell nicht einfach eine Zeile schreibt. Es kann nur einen Teil einer Zeile, oder auch mehrere Zeilen auf einmal schreiben.ice2k3 hat geschrieben:Bei jedem 1000 Mal wird die Datei 3-Mal geöffnet...
Aber das ist schon dran, wenn write() aufgerufen wird.Außerdem wird bei dem normalen stdout auch eine newline angehängt.
Das hat ja BlackJack schon ausgeführt.Und was ist das Problem mit dem Schreiben auf sys.__stdout__ ?
Aber nicht doch, sonst wärs ja ein qualifizierter Kommentar...Sag mal schaut hier keiner den Quelltext genau an bevor er hier nen unqualifizierten Kommentar abgibt.
Die Datei wird aber immer noch bei jedem Schreibzugriff geöffnet und wieder geschlossen. Das ist ineffizient. Sinnvoller wäre es, dass Dateiobjekt als Exemplarattribut zu setzen.ice2k3 hat geschrieben:Bei jedem 1000 Mal wird die Datei 3-Mal geöffnet...
Und was genau ist der Sinn und Zweck von Zeile zehn? Du öffnest da eine Datei, in die du nichts schreibst ...
Ich persönlich halte es für zweifelhaft, globale Attribute wie sys.stdout so zu manipulieren. Schließlich ist das letztlich nur eine schwache Variante des "logging"-Moduls.
Ich hab es früher mal so gelöst:
Was ich da mit dem try except pass wollte, weiß ich auch nicht mehr so genau.. vermutlich ging es mir darum, dass das Schreiben zum Originalen stdout immer funktioniert und dass mit der Datei ruhig Mist passieren kann. Das wäre sicherlich zu verfeinern
Code: Alles auswählen
logfilepath = 'log.log'
log_fd = open(logfilepath,'w')
sys.stdout = Tee(sys.stdout, log_fd)
sys.stderr = sys.stdout
class Tee(object):
"""
Provides a write()-method that writes to two filedescriptors.
One should be standard-stdout and the other should describe a real file.
If sys.stdout is replaced with an instance of this `Tee`-class and sys.stderr is
set to sys.stdout, all stdout+stderr of the script is collected to console and
to file at the same time.
"""
def __init__(self, stdout, file):
self.stdout = stdout
self.file = file
def write(self, data):
self.stdout.write(data)
try:
self.file.write(data)
self.file.flush()
except:
pass
[url]http://gehrcke.de[/url]
-
- User
- Beiträge: 2
- Registriert: Freitag 25. Mai 2018, 10:17
Hallo Zusammen,
ich hoffe dieses Thema findet noch Beachtung, wenn ich hier eine neue Frage poste.
Ich beschäftige mich ganz frisch mit Python und habe ehrlich nicht viel Ahnung davon.
Jedenfalls möchte ich einen Text, der auf dem Bildschirm ausgegeben wird auch in eine Textdatei speichern. Leider weiß ich nicht so recht, wie das geht.
Hier mal die funktionierende Zeile mit der Bildschirmausgabe:
else:
print(u'file loaded: {}\nMessage: {}'.format(audio_file, response['message']))
und so würde ich es in eine Textdatei speichern:
file = open(path/to/the/file/message.txt, "w+")
file.write(message.text)
file.close()
Nur so funktioniert es leider nicht und ich weiß nicht, wie ich diese Zeilen vernünftig in meinen Code bekomme... ich hoffe, ich konnte mich klar ausdrücken.
Vielen Dank schon mal für die Hilfe!
Lg Anna
ich hoffe dieses Thema findet noch Beachtung, wenn ich hier eine neue Frage poste.
Ich beschäftige mich ganz frisch mit Python und habe ehrlich nicht viel Ahnung davon.
Jedenfalls möchte ich einen Text, der auf dem Bildschirm ausgegeben wird auch in eine Textdatei speichern. Leider weiß ich nicht so recht, wie das geht.
Hier mal die funktionierende Zeile mit der Bildschirmausgabe:
else:
print(u'file loaded: {}\nMessage: {}'.format(audio_file, response['message']))
und so würde ich es in eine Textdatei speichern:
file = open(path/to/the/file/message.txt, "w+")
file.write(message.text)
file.close()
Nur so funktioniert es leider nicht und ich weiß nicht, wie ich diese Zeilen vernünftig in meinen Code bekomme... ich hoffe, ich konnte mich klar ausdrücken.
Vielen Dank schon mal für die Hilfe!
Lg Anna
Wenn du selbst überall die Kontrolle darüber hast, wann etwas ausgegeben wird, dann ist die einfachste Lösung den Text an einen Namen zu binden, und dann kannst du den ausgeben über beliebig viele Kanäle.
Und diese 4 Zeilen kannst du am besten in eine Funktion packen, zB log, und die dann immer aufrufen:
Code: Alles auswählen
message = u'file loaded: {}\nMessage: {}'.format(audio_file, response['message'])
print(message)
with open(“Datei”, “a”) as outf:
outf.write(message)
outf.write(“\n”) # print macht automatisch ein newline. write nicht.
Code: Alles auswählen
def log(message):
print...
log(u'file loaded: {}\nMessage: {}'.format(audio_file, response['message']))
-
- User
- Beiträge: 2
- Registriert: Freitag 25. Mai 2018, 10:17
Super, danke für die schnelle Antwort.
Ich werde es gleich mal probieren.
Ich werde es gleich mal probieren.