Python: Wie StringIO.writelines bekommen Unicode-String zu akzeptieren?
Frage
Ich bin immer ein
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 34: ordinal not in range(128)
auf einer Zeichenkette gespeichert in ‚a.desc‘ unten, wie es enthält den ‚£‘ Charakter. Es ist in der zugrunde liegenden Google App Engine-Datenspeicher als Unicode-String gespeichert, so das ist in Ordnung. Die cStringIO.StringIO.writelines Funktion versucht scheinbar versucht, es im ASCII-Format zu kodieren:
result.writelines(['blahblah',a.desc,'blahblahblah'])
Wie anweisen ich es die Codierung als Unicode zu behandeln, wenn das die richtige Formulierung ist?
App Engine läuft auf Python 2.5
Lösung
Im Gegensatz zu den Speicherdateien vom Modul StringIO implementiert, diejenigen, die von [cStringIO] sind nicht in der Lage Unicode-Strings zu akzeptieren, die nicht als reine ASCII-Zeichenfolge codiert werden kann.
Wenn möglich, verwenden StringIO statt cStringIO.
Andere Tipps
Sie können das StringIO Objekt in einem codecs.StreamReaderWriter
Objekt wickeln, um automatisch zu kodieren und dekodieren Unicode.
Wie folgt aus:
import cStringIO, codecs
buffer = cStringIO.StringIO()
codecinfo = codecs.lookup("utf8")
wrapper = codecs.StreamReaderWriter(buffer,
codecinfo.streamreader, codecinfo.streamwriter)
wrapper.writelines([u"list of", u"unicode strings"])
buffer
mit UTF-8-codierten Bytes gefüllt werden.
Wenn ich Ihren Fall richtig verstanden habe, werden Sie nur schreiben müssen, so könnte man auch tun:
import cStringIO, codecs
buffer = cStringIO.StringIO()
wrapper = codecs.getwriter("utf8")(buffer)
Sie können auch Ihre Zeichenfolge als utf-8 manuell codieren, bevor es die StringIO Hinzufügen
for val in rows:
if isinstance(val, unicode):
val = val.encode('utf-8')
result.writelines(rows)
Python 2.6 eingeführt, um die io
Modul und Sie sollten erwägen, io.StringIO()
"ein in-Memory-Stream für Unicode-Text."
Bei älteren Python-Versionen ist dies nicht optimiert (reiner Python), in späteren Versionen hat dies zu (fast) optimiert C-Code.