Подтвердить что ты не робот

Python: Как заставить StringIO.writelines принимать строку Unicode?

Я получаю

UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 34: ordinal not in range(128)

в строке, хранящейся в 'a.desc' ниже, поскольку она содержит символ 'E'. Он хранится в базовом хранилище данных Google App Engine в виде строки в Юникоде, так что это нормально. Функция cStringIO.StringIO.writelines пытается, по-видимому, пытаться кодировать ее в формате ascii:

result.writelines(['blahblah',a.desc,'blahblahblah'])

Как мне дать указание обработать кодировку как unicode, если это правильная фраза?

движок приложения работает на python 2.5

4b9b3361

Ответ 1

Документация по StringIO:

В отличие от файлов памяти, реализованных модулем StringIO, те, которые предоставляются [cStringIO], не могут принимать строки Unicode, которые не могут быть закодированы как простые строки ASCII.

Если возможно, используйте StringIO вместо cStringIO.

Ответ 2

Вы можете обернуть объект 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)

Ответ 3

Вы также можете закодировать свою строку как utf-8 вручную, прежде чем добавлять ее в StringIO

for val in rows:
    if isinstance(val, unicode):
        val = val.encode('utf-8')
result.writelines(rows)

Ответ 4

Python 2.6 представил модуль io, и вы должны рассмотреть возможность использования io.StringIO(), "поток в памяти для текста в Юникоде".

В более старых версиях python это не оптимизировано (чистый Python), в более поздних версиях он оптимизирован для быстрого кода C.