web-dev-qa-db-ja.com

Python:StringIO.writelinesを取得してUnicode文字列を受け入れる方法は?

私は

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

'£'文字が含まれているため、以下の 'a.desc'に格納されている文字列。基盤となるGoogleApp EngineデータストアにUnicode文字列として保存されるため、問題ありません。 cStringIO.StringIO.writelines関数は、ASCII形式でエンコードしようとしているようです。

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

それが正しい言い回しである場合、エンコーディングをユニコードとして扱うように指示するにはどうすればよいですか?

アプリエンジンはpython 2.5

24
rutherford

StringIOドキュメント

StringIOモジュールによって実装されるメモリファイルとは異なり、[cStringIO]によって提供されるメモリファイルは、プレーンなASCII文字列としてエンコードできないUnicode文字列を受け入れることができません。

可能であれば、cStringIOの代わりにStringIOを使用してください。

22
Phil

StringIOオブジェクトをcodecs.StreamReaderWriterオブジェクトでラップして、Unicodeを自動的にエンコードおよびデコードできます。

このような:

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)
38
codeape

StringIOに追加する前に、文字列をutf-8として手動でエンコードすることもできます。

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

Python2.6ではioモジュールが導入されたため、 io.StringIO() 、「Unicodeテキストのメモリ内ストリーム」の使用を検討する必要があります。

古いpythonバージョンでは、これは最適化されていません(純粋なPython)。新しいバージョンでは、これは(高速)Cコードに最適化されています。

0
Anthon