Python: Как заставить StringIO.writelines принимать строки в юникоде?
Вопрос
Я получаю
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 34: ordinal not in range(128)
в строке, хранящейся в «a.desc» ниже, так как она содержит «& # 163;» персонаж. Он хранится в базовом хранилище данных Google App Engine в виде строки Unicode, так что это нормально. Функция cStringIO.StringIO.writelines, похоже, пытается закодировать ее в формате ascii:
result.writelines(['blahblah',a.desc,'blahblahblah'])
Как мне дать ему указание обрабатывать кодировку как юникод, если это правильная формулировка?
движок приложения работает на python 2.5
Решение
В отличие от файлов памяти, реализованных модулем StringIO, файлы, предоставляемые [cStringIO], не способны принимать строки Unicode, которые нельзя кодировать как простые строки ASCII.
Если возможно, используйте StringIO вместо cStringIO.
Другие советы
Вы можете обернуть объект StringIO в объект codecs.StreamReaderWriter
для автоматического кодирования и декодирования юникода.
Вот так:
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
будет заполнен байтами в кодировке utf-8.
Если я правильно понимаю ваше дело, вам нужно будет только написать, так что вы также можете сделать:
import cStringIO, codecs
buffer = cStringIO.StringIO()
wrapper = codecs.getwriter("utf8")(buffer)
Вы также можете вручную закодировать строку как utf-8, прежде чем добавить ее в StringIO
for val in rows:
if isinstance(val, unicode):
val = val.encode('utf-8')
result.writelines(rows)
Python 2.6 представил модуль io
, и вы должны рассмотреть возможность использования io.StringIO ()
, " поток в памяти для текста в Unicode. "
В более старых версиях Python это не оптимизировано (чистый Python), в более поздних версиях это оптимизировано для (быстрого) C-кода.