2009-11-30 17 views
23

それは£ '文字が含まれているように私には、以下の「a.desc」に格納されている文字列のPython:Unicode文字列を受け入れるStringIO.writelinesを取得するには?

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

を取得しています。これは基本的なGoogle App Engineのデータストアにユニコード文字列として格納されているので問題ありません。 cStringIO.StringIO.writelines機能は一見のASCII形式でエンコードしようと試みている:

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

私はそれが正しい言い回しだ場合、それはUnicodeとしてエンコードを扱うように指示するにはどうすればよいですか?

アプリエンジンは、Python 2.5

答えて

21

StringIO documentation上で実行される:

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

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

+1

私は(cStringIOはパフォーマンスに優れていることを意味します)スイッチを入れましたが、エラーは発生しませんでしたが、 '£'の代わりに '£'が表示されました。 なぜ「Â」が表示されますか? – rutherford

+4

'£'は、u'£ 'のUTF-8エンコーディングである0xc2 0xa3のWindows-1252デコードです。あなたの端末、アプリ、またはあなたが見ているところは、UTF-8の代わりにWindows-1252用に設定されているかもしれません。 – Phil

+0

hmm。基本的には、私はChromeブラウザを通じてWebサーバーの応答を見ています。それが問題だろうか? – rutherford

36

codecs.StreamReaderWriterオブジェクトにStringIOオブジェクトをラップして、ユニコードを自動的にエンコードおよびデコードすることができます。このよう

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) 
+1

また、 'cStringIO.StringIO()'によって返されたファイルのようなオブジェクトは 'with'ステートメントでは動作しませんが、' codecs.StreamReaderWriter() 'によって返されたラッパーは動作します! – steveha

+0

これはhttps://stackoverflow.com/q/45101658/562769に似て聞こえる - 私の質問に対する答えを知っていますか? –

3

はまた、手動たStringIO

に追加する前に、UTF-8など、あなたの文字列をエンコードすることができます
for val in rows: 
    if isinstance(val, unicode): 
     val = val.encode('utf-8') 
result.writelines(rows) 
+2

'type is X'の代わりに' isinstance'を使います – chown

0

Python 2.6でioモジュールが導入されました。io.StringIO()「ユニコードテキスト用のメモリ内ストリーム」の使用を検討する必要があります。

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

関連する問題