Warum kann ich in write () keine Zeichenfolge für eine neue Zeile verwenden, aber in writelines ()?
Die Idee ist folgende: Wenn Sie eine einzelne Zeichenfolge schreiben möchten, können Sie dies tun write()
. Wenn Sie eine Folge von Zeichenfolgen haben, können Sie diese alle mit schreiben writelines()
.
write(arg)
erwartet einen String als Argument und schreibt ihn in die Datei. Wenn Sie eine Liste von Zeichenfolgen angeben, wird eine Ausnahme ausgelöst (zeigen Sie uns übrigens Fehler!).
writelines(arg)
erwartet ein iterierbares Argument (ein iterierbares Objekt kann im allgemeinsten Sinne ein Tupel, eine Liste, eine Zeichenfolge oder ein Iterator sein). Es wird erwartet, dass jedes im Iterator enthaltene Element eine Zeichenfolge ist. Ein Tupel von Zeichenfolgen ist das, was Sie bereitgestellt haben, also haben die Dinge funktioniert.
Die Art der Zeichenfolge (n) spielt für beide Funktionen keine Rolle, dh sie schreiben einfach in die Datei, was auch immer Sie ihnen zur Verfügung stellen. Der interessante Teil ist, dass writelines()
keine Zeilenumbruchzeichen hinzugefügt werden, sodass der Methodenname tatsächlich ziemlich verwirrend sein kann. Es verhält sich tatsächlich wie eine imaginäre Methode namens write_all_of_these_strings(sequence)
.
Was folgt, ist eine idiomatische Methode in Python, um eine Liste von Zeichenfolgen in eine Datei zu schreiben, während jede Zeichenfolge in einer eigenen Zeile bleibt:
lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
f.write('\n'.join(lines))
Dadurch wird die Datei für Sie geschlossen. Das Konstrukt '\n'.join(lines)
verkettet (verbindet) die Zeichenfolgen in der Liste lines
und verwendet das Zeichen '\ n' als Klebstoff. Es ist effizienter als die Verwendung des +
Operators.
Ausgehend von derselben lines
Sequenz, endend mit derselben Ausgabe, aber mit writelines()
:
lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
f.writelines("%s\n" % l for l in lines)
Dies verwendet einen Generatorausdruck und erstellt dynamisch Zeichenfolgen mit Zeilenumbruch. writelines()
iteriert über diese Folge von Zeichenfolgen und schreibt jedes Element.
Bearbeiten: Ein weiterer Punkt, den Sie beachten sollten:
write()
und readlines()
existierte, bevor writelines()
eingeführt wurde. writelines()
wurde später als Gegenstück zu eingeführt readlines()
, so dass man den Dateiinhalt, der gerade gelesen wurde, leicht schreiben konnte über readlines()
:
outfile.writelines(infile.readlines())
Wirklich, das ist der Hauptgrund, warum writelines
so ein verwirrender Name hat. Auch heute wollen wir diese Methode nicht mehr wirklich anwenden. readlines()
Liest die gesamte Datei in den Speicher Ihres Computers, bevor writelines()
mit dem Schreiben der Daten begonnen wird. Dies kann zuallererst Zeit verschwenden. Warum nicht anfangen, Teile von Daten zu schreiben, während Sie andere Teile lesen? Vor allem aber kann dieser Ansatz sehr speicherintensiv sein. In einem extremen Szenario, in dem die Eingabedatei größer als der Speicher Ihres Computers ist, funktioniert dieser Ansatz nicht einmal. Die Lösung für dieses Problem besteht darin, nur Iteratoren zu verwenden. Ein Arbeitsbeispiel:
with open('inputfile') as infile:
with open('outputfile') as outfile:
for line in infile:
outfile.write(line)
Dies liest die Eingabedatei Zeile für Zeile. Sobald eine Zeile gelesen wurde, wird diese Zeile in die Ausgabedatei geschrieben. Schematisch gesehen befindet sich immer nur eine einzige Zeile im Speicher (im Vergleich zum gesamten Dateiinhalt im Speicher, wenn der Readlines / Writelines-Ansatz verwendet wird).
lines
ist in Ihrem Beispiel keine Zeichenfolge. Es ist ein Tupel, das aus sechs Saiten besteht.