2010-11-03 4 views
6

Ich habe eine Reihe von print Anrufe, die ich in eine Datei statt stdout schreiben muss. (Ich brauche überhaupt nicht stdout.)Drucken in eine Datei in Python: Redirect vs Print Datei Argument vs schreiben

Ich betrachte drei Ansätze. Gibt es irgendwelche Vorteile (einschließlich der Leistung) für einen von ihnen?

Voll Umleitung, die ich here sah:

import sys 

saveout = sys.stdout 
fsock = open('out.log', 'w') 
sys.stdout = fsock 

print(x) 
# and many more print calls 

# later if I ever need it: 
# sys.stdout = saveout 
# fsock.close() 

Redirect in jedem Druck Aussage:

fsock = open('out.log', 'w') 
print(x, file = fsock) 
# and many more print calls 

Write-Funktion:

fsock = open('out.log', 'w') 
fsock.write(str(x)) 
# and many more write calls 
+0

Wenn Sie py3k verwenden, lesen [diveintopython 3] (http://diveintopython3.org/) – SilentGhost

+0

habe vergessen hinzuzufügen, dass ich vor kurzem eine verwandte Frage gestellt habe. http://stackoverflow.com/questions/4090652/where-to-store-a-log-file-name-in-python – max

+0

Im Zweifelsfall Profil. http://docs.python.org/py3k/library/profile.html –

Antwort

6

Ich würde keine dauerhaften Leistungsunterschiede zwischen diesen Ansätzen erwarten.

Der Vorteil des ersten Ansatzes besteht darin, dass jeder vernünftige Code, auf den Sie sich verlassen (importierte Module), automatisch die gewünschte Umleitung annimmt.

Der zweite Ansatz hat keinen Vorteil. Es ist nur zum Debuggen oder Wegwerfen von Code geeignet ... und nicht einmal eine gute Idee dafür. Sie möchten, dass Ihre Ausgabeentscheidungen an einigen gut definierten Orten konsolidiert werden und nicht bei jedem Anruf auf print() über Ihren Code verteilt werden. In Python3 ist print() eine Funktion und keine Anweisung. Dies ermöglicht es Ihnen, es neu zu definieren, wenn Sie möchten. So können Sie def print(*args) wenn Sie möchten. Sie können auch __builtins__.print() aufrufen, wenn Sie Zugriff darauf benötigen, beispielsweise in der Definition Ihrer eigenen benutzerdefinierten print().

Der dritte Ansatz ... und damit das Prinzip, dass alle Ihre Ausgaben in bestimmten Funktionen und Klassenmethoden erzeugt werden sollten, die Sie für diesen Zweck definieren ... ist wahrscheinlich am besten.

Sie sollten Ihre Ausgabe und Formatierung so weit wie möglich von Ihrer Kernfunktionalität getrennt halten. Indem Sie sie getrennt halten, erlauben Sie, dass Ihr Kern wiederverwendet wird. (Sie könnten beispielsweise mit etwas beginnen, das von einer text/shell-Konsole ausgeführt werden soll, und später eine Web-Benutzeroberfläche, ein Vollbild-Frontend oder eine GUI dafür bereitstellen. Sie können auch völlig andere Funktionen erstellen um es herum ...in Situationen, in denen die resultierenden Daten in ihrer nativen Form (als Objekte) zurückgegeben werden müssen, anstatt als Text (Ausgabe) eingezogen und erneut in neue Objekte zerlegt zu werden.

Zum Beispiel hatte ich mehr als nur gelegentlich, wo ich etwas geschrieben habe, um einige komplexe Abfragen und Datenerfassungen aus verschiedenen Quellen durchzuführen und einen Bericht zu drucken ... sagen von den Diskrepanzen ... später müssen in angepasst werden Formular, das die Daten in irgendeiner Form (wie YAML/JSON) ausspeien könnte, die in ein anderes System eingespeist werden könnten (z. B. um eine Datenquelle mit einer anderen zu verstimmen.) Wenn Sie von Anfang an die Hauptdaten behalten Operationen getrennt von der Ausgabe und Formatierung dann ist diese Art der Anpassung relativ einfach, sonst bringt es ziemlich viel Refactoring mit sich (manchmal gleichbedeutend mit einem kompletten Neuschreiben).

4

Aus den Dateinamen Sie verwenden in Ihre Frage, es klingt wie Sie eine Protokolldatei erstellen möchten. Hast du stattdessen das Python logging Modul in Betracht gezogen?

+0

siehe OP jüngste Geschichte – SilentGhost

+0

Am Ende entschied ich mich gegen 'Logging'. Ich habe mehrere Dateien zu schreiben, und ich fand es einfacher, auf eigene Faust zu verwalten. Aber danke, ich werde es mir merken. – max

4

Ich denke, dass Semantik imporant ist:

Ich würde ersten Ansatz für Situation vorschlagen, wenn Sie die gleichen Sachen Drucken Sie auf Konsole drucken. Semantik wird gleich sein. Für komplexere Situationen würde ich das Standardprotokollierungsmodul verwenden.

Der zweite und dritte Ansatz unterscheiden sich ein wenig, wenn Sie Textzeilen drucken. Zweiter Ansatz - print fügt die neue Zeile hinzu und write nicht.

Ich würde den dritten Ansatz im Schreiben hauptsächlich binäres oder non-textual Format verwenden und ich würde Redirect in der Druckanweisung in den meisten anderen Fällen verwenden.

+1

+1: Newline-Info. – max