2010-10-26 13 views
9

Ich schreibe eine Reihe von SQL-Anweisungen in eine Datei mit Python. Die Vorlage Zeichenfolge wie folgt aussieht:Python file.write Erstellen zusätzlicher Wagenrücklauf

store_insert = '\tinsert stores (storenum, ...) values (\'%s\', ...)' 

Ich mag so in die Datei Ich schreibe:

for line in source: 
    line = line.rstrip() 
    fields = line.split('\t') 
    script.write(store_insert % tuple(fields)) 
    script.write(os.linesep) 

jedoch in der resultierenden Ausgabe, sehe ich \ r \ r \ n am Ende jeder Linie, anstatt wie ich es erwarten würde. Warum?

+1

'%' String Formatierung ist jetzt alt; Das bevorzugte Idiom ist 'str.format' =) – katrielalex

+4

Haben Sie die Datei im Text- oder Binärmodus geöffnet? Welches Betriebssystem verwenden Sie? – AndiDog

+0

Windows und ich habe gerade eine offene (Datei, 'r') – Chris

Antwort

20

\n wird in os.linesep für Dateien konvertiert, die im Textmodus geöffnet werden. Wenn Sie also os.linesep in eine Textmodusdatei unter Windows schreiben, schreiben Sie \r\n, und \n wird konvertiert, was zu \r\r\n führt.

Siehe auch the docs:

nicht os.linesep als Zeilenendzeichen verwenden, wenn Dateien geöffnet im Textmodus (Standardeinstellung) zu schreiben; Verwenden Sie stattdessen ein einzelnes \ n auf allen Plattformen.

+0

+1 gut gefunden! Dies passiert nicht wirklich für mich (Win7), vielleicht ist es eine Windows-abhängige Sache? – katrielalex

+0

Ich benutze auch Windows 7, aber das erklärt es. +1 und Antwort! – Chris

0

siehe open() doc:

Neben dem Standard fopen() -Werten Modus 'U' oder 'rU' sein kann. Python wird normalerweise mit universellen Newline-Unterstützung gebaut; Wenn Sie 'U' angeben, wird die Datei als Textdatei geöffnet, Zeilen können jedoch durch eines der folgenden Ereignisse beendet werden: die Unix-Endkonvention '\ n', die Macintosh-Konvention '\ r' oder die Windows-Konvention '\' r \ n '. Alle diese externen Repräsentationen werden vom Python-Programm als '\ n' angesehen. Wenn Python ohne universelle Newline-Unterstützung erstellt wird, entspricht ein Modus mit "U" dem normalen Textmodus. Beachten Sie, dass so geöffnete Dateiobjekte auch ein Attribut namens newlines haben, das den Wert None (wenn noch keine Zeilenvorschübe vorhanden sind), '\ n', '\ r', '\ r \ n' oder ein Tupel, das alle enthält, enthält die Newline-Typen gesehen.

+0

Na und? Der Universal-Newline-Modus dient nur zum Lesen. – AndiDog

+0

@AndiDog: Ich denke, was er sagt ist, dass, wenn er eine Datei mit offenen öffnen ('', 'r') nachdem er darauf geschrieben hat er sehen \ r \ r \ n und er denkt, dass er nur schrieb ' \ r \ n '(Fenster), also sagte ich ihm, dass, wenn er seine Datei öffnet, open() automatisch \ r \ n zu seinen Daten hinzufügt, also' \ r \ n '+' \ r \ n '=' \ r \ r \ n ', das' \ n 'ist entfernt Wollen Sie, dass ich mehr ausarbeite ??? – mouad

+1

Nein Ich verwende tatsächlich eine separate Ausgabedatei, die mit open geöffnet wurde (Datei, 'w'). Ändern zu öffnen (Datei, 'wb') behoben das Problem, aber ich bin mir nicht ganz sicher, ich verstehe, warum – Chris

1

Werke für mich:

>>> import tempfile 
>>> tmp = tempfile.TemporaryFile(mode="w+") 
>>> store_insert = '\tinsert stores (storenum, ...) values (\'%s\', ...)' 
>>> lines = ["foo\t\t"] 
>>> for line in lines: 
...  line = line.rstrip() 
...  fields = line.split("\t") 
...  tmp.write(store_insert % tuple(fields)) 
...  tmp.write(os.linesep) 
... 
>>> tmp.seek(0) 
>>> tmp.read() 
"\tinsert stores (storenum, ...) values ('foo', ...)\r\n" 

Sind Sie sicher, dass dies der Code, der ausgeführt wird, dass os.linesep ist das, was Sie denken, es ist, etc?

3

Textdateien haben auf verschiedenen Betriebssystemen unterschiedliche Zeilenenden, aber es ist bequem, mit Strings zu arbeiten, die ein konsistentes Zeilenendezeichen haben. Python erbt die Konvention von C, '\n' als universelles Zeilenendezeichen zu verwenden und sich auf die Lese- und Schreibfunktionen der Datei zu verlassen, um bei Bedarf eine Konvertierung durchzuführen. Die Lese- und Schreibfunktionen wissen dies, wenn die Datei im Standardmodus text geöffnet wurde. Wenn Sie beim Öffnen der Datei das Zeichen b zu der Moduszeichenfolge hinzufügen, wird diese Übersetzung übersprungen.

3

Python 3

os.open() stellt den neuen Parameter newline die eine Zeichenfolge, die jedes Vorkommen von \n angeben können wird übersetzt werden.

Das Übergeben eines leeren String-Arguments newline='' deaktiviert die Übersetzung und lässt den neuen Zeilencode unverändert. Nur für den Textmodus gültig.

From the documentation

On-Ausgang, wenn newline None ist, werden alle '\ n' Zeichen an das System Standardlinientrenner, os.linesep übersetzt geschrieben. Wenn newline '' ist, findet keine Übersetzung statt. Wenn newline einen der anderen zulässigen Werte hat, werden alle geschriebenen \ n-Zeichen in die angegebene Zeichenfolge übersetzt.

+0

Für einen Anwendungsfall und einige Ausarbeitung, siehe [hier] (http://stackoverflow.com/questions/43528959/python-3-how-to-pass-binary-file-as-text-without-saving-first) – RolfBly

Verwandte Themen