2016-07-31 8 views
0

Ich versuche, einen Python 2.x Version dieses Codes zu konvertieren:Konvertieren und Schreiben Liste von Strings als binäre in Python 3

out_chunk = open('out.txt','w+b') 
chunks.append(out_chunk) # out_chunk is just a list of strings like ['a', 'b', ...] 
out_chunk.writelines(chunk) 

in Python 3.x-Version. Wenn ich den obigen Code in Python 3.x direkt ausführen, bekomme ich einen Fehler wie unten, von der erwartet wird:

Traceback (most recent call last): 
    File "C:/Users/Desktop/es/prog.py", line 145, in <module> 
    ob.external_sort() 
    File "C:/Users/Desktop/es/prog.py", line 70, in my_func 
    out_chunk.writelines(chunk) 
TypeError: a bytes-like object is required, not 'str' 

Gibt es eine Möglichkeit Liste von Strings als Bytes in Python 3.x zu schreiben? Oder sollte ich schreibe einfach als Liste von Strings (und die Leistung Hit nehmen, vielleicht?)

+0

Warum erstellt Ihre Python 3-Version keine Byte-Objekte? –

Antwort

3

Sie haben die Datei in binäre-Modus geöffnet, so dass Sie Ihre Bytes kodieren müssen.

Wenn Sie den 'b' Teil aus der Datei-Modus fallen (so offen mit 'w+' statt 'w+b'), können Sie eine Implementierung des TextIOBase interface stattdessen bekommen, die Strings kodieren für Sie eine Codierung gegeben (der Standard ist das Ergebnis zu verwenden von locale.getdefaultencoding(), möchten Sie wahrscheinlich stattdessen ein explizites encoding Argument zum open() Aufruf liefern).

Die Alternative wäre für Sie, Ihre Zeichenfolgen manuell zu codieren, die str.encode() method auf jedem Stück verwenden. Die Kodierung zu der TextIOBase-Implementierung zu belassen wird jedoch ein wenig schneller sein, da die E/A-Schicht codieren kann, ohne ein Methodenobjekt auf jedem str Chunk nachschlagen zu müssen, noch müssen die resultierenden Bytes in einem Python bytes-Objekt eingerahmt werden nochmal.

Auch für Kodierungen, die eine byte order mark erfordern, ist es am besten, diesen Marker für die Dateiimplementierung zu schreiben.

Wenn Sie jedoch in erster Linie bytes Objekte produzieren könnten, würden Sie vermeiden, überhaupt kodieren zu müssen.

1

Nur nicht öffnen Sie die Datei in Binär-Modus:

out_chunk = open('out.txt','w+') 

Hoffe, es hilft!

+0

Ja, das habe ich mir gedacht. Aber ich frage mich, ob das Schreiben einer Liste von Zeichenfolgen als Binärzeichen einen Leistungsgewinn im Gegensatz zu einfach dem Schreiben von Text-E/A hinzufügen könnte. Hoffentlich kann jemand, der Python 3.x IO Verhalten gut kennt, hier kommentieren. :) Danke für deinen Vorschlag. – user1330974

+1

Mach dir keine Sorgen wegen einer solchen Optimierung in einem kleinen Fall, wie sie sich in einer kleinen Python-Version ändern könnte. Wenn Sie Python3-Zeichenfolgen (Unicode-Zeichenfolgen) haben und diese in eine Textdatei schreiben möchten, müssen Sie sie zuerst codieren. Sie können entweder explizit codieren und dann in eine Binärdatei schreiben oder die TextIO-Engine eine implizite Codierung ausführen lassen. Irgendwie ist die gleiche Kodierung erfolgt, daher sollte die Leistung sehr nahe sein. –

+1

@SergeBallesta: Nun, die TextIOBase-Implementierung muss weder das '.encode'-Attribut für jeden Chunk auflösen, noch den aktuellen Frame auf dem Stack verschieben, um den Aufruf auszuführen, noch das' bytes'-Objekt erstellen (es kann die Bytes einfach als C-Array belassen, um es an den eingepackten Puffer weiterzugeben). –