Python: Как заставить StringIO.writelines принимать строки в юникоде? - PullRequest
24 голосов
/ 30 ноября 2009

Я получаю

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

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

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

Как мне дать ему указание обрабатывать кодировку как юникод, если это правильное выражение?

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

Ответы [ 4 ]

38 голосов
/ 30 ноября 2009

Вы можете обернуть объект 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)
22 голосов
/ 30 ноября 2009

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

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

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

3 голосов
/ 11 мая 2012

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

for val in rows:
    if isinstance(val, unicode):
        val = val.encode('utf-8')
result.writelines(rows)
0 голосов
/ 11 сентября 2014

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

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

...