Ich möchte ein Python-Skript ausführen und die Ausgabe in einer Textdatei erfassen sowie auf der Konsole anzeigen.
Ich möchte es als eine Eigenschaft des Python-Skripts selbst angeben. Verwenden Sie den Befehl NICHT echo "hello world" | tee test.txt
jedes Mal an der Eingabeaufforderung.
Innerhalb des Skripts habe ich versucht:
sys.stdout = open('log.txt','w')
Dies zeigt jedoch nicht die Standardausgabe auf dem Bildschirm.
Ich habe von einem Protokollierungsmodul gehört, aber ich konnte kein Glück haben, dieses Modul für die Arbeit zu verwenden.
quelle
sys.stdout
Verhalten zurück? Angenommen, ich möchte dies, aber nur in der Startphase meines Programms, und nach einer Weile möchte ich das Programm einfach laufen lassen, ohne alles zu speichernsys.stdout
in Logger speichern und eine Funktion erstellen, die es in den ursprünglichen Zustand zurücksetzt .Ich habe die Möglichkeit, die Ausgabe gleichzeitig an die Konsole sowie an eine Textdatei umzuleiten:
te = open('log.txt','w') # File where you need to keep the logs class Unbuffered: def __init__(self, stream): self.stream = stream def write(self, data): self.stream.write(data) self.stream.flush() te.write(data) # Write the data of stdout here to a text file as well sys.stdout=Unbuffered(sys.stdout)
quelle
Verwenden Sie das Protokollierungsmodul, um Ihre App zu debuggen und zu verfolgen
Hier ist, wie ich es geschafft habe, mich in einer Datei und in console / stdout anzumelden
import logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', filename='logs_file', filemode='w') # Until here logs only to file: 'logs_file' # define a new Handler to log to console as well console = logging.StreamHandler() # optional, set the logging level console.setLevel(logging.INFO) # set a format which is the same for console use formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') # tell the handler to use this format console.setFormatter(formatter) # add the handler to the root logger logging.getLogger('').addHandler(console) # Now, we can log to both ti file and console logging.info('Jackdaws love my big sphinx of quartz.') logging.info('Hello world')
Lesen Sie es aus der Quelle: https://docs.python.org/2/howto/logging-cookbook.html
quelle
Ich habe eine einfachere Lösung gefunden. Definieren Sie einfach eine Funktion, die in eine Datei oder auf einen Bildschirm oder in beide gedruckt wird. Im folgenden Beispiel erlaube ich dem Benutzer, den Namen der Ausgabedatei als Argument einzugeben, aber das ist nicht obligatorisch:
OutputFile= args.Output_File OF = open(OutputFile, 'w') def printing(text): print text if args.Output_File: OF.write(text + "\n")
Danach ist alles, was zum Drucken einer Zeile sowohl in die Datei als auch in den Bildschirm benötigt wird, Folgendes: Drucken (Line_to_be_printed)
quelle
str(text)
, um ihn in einen String umzuwandeln.Basierend auf der Antwort von Amith Koujalgi ist hier ein einfaches Modul, das Sie zum Protokollieren verwenden können:
transkript.py:
""" Transcript - direct print output to a file, in addition to terminal. Usage: import transcript transcript.start('logfile.log') print("inside file") transcript.stop() print("outside file") """ import sys class Transcript(object): def __init__(self, filename): self.terminal = sys.stdout self.logfile = open(filename, "a") def write(self, message): self.terminal.write(message) self.logfile.write(message) def flush(self): # this flush method is needed for python 3 compatibility. # this handles the flush command by doing nothing. # you might want to specify some extra behavior here. pass def start(filename): """Start transcript, appending print output to given filename""" sys.stdout = Transcript(filename) def stop(): """Stop transcript and return print functionality to normal""" sys.stdout.logfile.close() sys.stdout = sys.stdout.terminal
quelle
from IPython.utils.io import Tee from contextlib import closing print('This is not in the output file.') with closing(Tee("outputfile.log", "w", channel="stdout")) as outputstream: print('This is written to the output file and the console.') # raise Exception('The file "outputfile.log" is closed anyway.') print('This is not written to the output file.') # Output on console: # This is not in the output file. # This is written to the output file and the console. # This is not written to the output file. # Content of file outputfile.txt: # This is written to the output file and the console.
Die
Tee
Klasse inIPython.utils.io
macht, was Sie wollen, aber es fehlen die__enter__
und__exit__
Methoden, die erforderlich sind, um sie in derwith
Anweisung aufzurufen. Diese werden von hinzugefügtcontextlib.closing
.quelle
Ich habe hier einige Lösungen ausprobiert und nicht die gefunden, die gleichzeitig in eine Datei und in eine Konsole schreibt. Also hier ist was ich getan habe (basierend auf dieser Antwort)
class Logger(object): def __init__(self): self.terminal = sys.stdout def write(self, message): with open ("logfile.log", "a", encoding = 'utf-8') as self.log: self.log.write(message) self.terminal.write(message) def flush(self): #this flush method is needed for python 3 compatibility. #this handles the flush command by doing nothing. #you might want to specify some extra behavior here. pass sys.stdout = Logger()
Diese Lösung verbraucht mehr Rechenleistung, speichert jedoch zuverlässig alle Daten von stdout in der Logger-Datei und benötigt weniger Speicher. Für meine Bedürfnisse habe ich auch einen Zeitstempel in self.log.write (Nachricht) hinzugefügt. Funktioniert super.
quelle
Hier ist ein einfacher Kontextmanager, der auf der Konsole druckt und dieselbe Ausgabe in eine Datei schreibt. Es werden auch alle Ausnahmen in die Datei geschrieben.
import traceback import sys # Context manager that copies stdout and any exceptions to a log file class Tee(object): def __init__(self, filename): self.file = open(filename, 'w') self.stdout = sys.stdout def __enter__(self): sys.stdout = self def __exit__(self, exc_type, exc_value, tb): sys.stdout = self.stdout if exc_type is not None: self.file.write(traceback.format_exc()) self.file.close() def write(self, data): self.file.write(data) self.stdout.write(data) def flush(self): self.file.flush() self.stdout.flush()
So verwenden Sie den Kontextmanager:
print("Print") with Tee('test.txt'): print("Print+Write") raise Exception("Test") print("Print")
quelle
Um die Ausgabe in eine Datei und ein Terminal umzuleiten, ohne die Verwendung Ihres Python-Skripts im Freien zu ändern, können Sie Folgendes verwenden
pty.spawn(itself)
:#!/usr/bin/env python """Redirect stdout to a file and a terminal inside a script.""" import os import pty import sys def main(): print('put your code here') if __name__=="__main__": sentinel_option = '--dont-spawn' if sentinel_option not in sys.argv: # run itself copying output to the log file with open('script.log', 'wb') as log_file: def read(fd): data = os.read(fd, 1024) log_file.write(data) return data argv = [sys.executable] + sys.argv + [sentinel_option] rc = pty.spawn(argv, read) else: sys.argv.remove(sentinel_option) rc = main() sys.exit(rc)
Wenn das
pty
Modul nicht verfügbar ist (unter Windows), können Sie es durch eine portablereteed_call()
Funktion ersetzen , die jedoch normale Pipes anstelle eines Pseudo-Terminals bereitstellt. Dies kann das Verhalten einiger Programme ändern.Der Vorteil von
pty.spawn
undsubprocess.Popen
-basierten Lösungen gegenüber dem Ersetzensys.stdout
durch ein dateiähnliches Objekt besteht darin, dass sie die Ausgabe auf Dateideskriptorebene erfassen können, z. B. wenn das Skript andere Prozesse startet, die auch eine Ausgabe auf stdout / stderr erzeugen können. Siehe meine Antwort auf die verwandte Frage: Stdout in eine Datei in Python umleiten?quelle
Basierend auf der von Brian Burns bearbeiteten Antwort habe ich eine einzelne Klasse erstellt, die einfacher aufzurufen ist:
class Logger(object): """ Class to log output of the command line to a log file Usage: log = Logger('logfile.log') print("inside file") log.stop() print("outside file") log.start() print("inside again") log.stop() """ def __init__(self, filename): self.filename = filename class Transcript: def __init__(self, filename): self.terminal = sys.stdout self.log = open(filename, "a") def __getattr__(self, attr): return getattr(self.terminal, attr) def write(self, message): self.terminal.write(message) self.log.write(message) def flush(self): pass def start(self): sys.stdout = self.Transcript(self.filename) def stop(self): sys.stdout.log.close() sys.stdout = sys.stdout.terminal
quelle
Ich habe es versucht:
""" Transcript - direct print output to a file, in addition to terminal. Usage: import transcript transcript.start('logfile.log') print("inside file") transcript.stop() print("outside file") """ import sys class Transcript(object): def __init__(self, filename): self.terminal = sys.stdout, sys.stderr self.logfile = open(filename, "a") def write(self, message): self.terminal.write(message) self.logfile.write(message) def flush(self): # this flush method is needed for python 3 compatibility. # this handles the flush command by doing nothing. # you might want to specify some extra behavior here. pass def start(filename): """Start transcript, appending print output to given filename""" sys.stdout = Transcript(filename) def stop(): """Stop transcript and return print functionality to normal""" sys.stdout.logfile.close() sys.stdout = sys.stdout.terminal sys.stderr = sys.stderr.terminal
quelle
Sie können die Ausgabe in eine Datei umleiten, indem Sie >> python mit der in den Dokumenten angegebenen "Chevron" -Syntax von print rint verwenden
mal sehen,
fp=open('test.log','a') # take file object reference print >> fp , "hello world" #use file object with in print statement. print >> fp , "every thing will redirect to file " fp.close() #close the file
Checken Sie die Datei test.log aus, Sie haben die Daten und um auf der Konsole zu drucken, verwenden Sie einfach eine einfache Druckanweisung .
quelle
>>
ist nicht der Umleitungsoperator, sondern der Schichtoperator. Ändern Sie dies bitte.