2009-11-30 72 views
23

我得到一個Python:如何讓StringIO.writelines接受unicode字符串?

UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 34: ordinal not in range(128) 
下面存儲在「a.desc」字符串

,因爲它包含了「£」字。它以unicode字符串的形式存儲在底層的Google App Engine數據存儲區中,所以沒關係。該cStringIO.StringIO.writelines函數試圖看似試圖對其進行編碼,以ASCII格式:

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

如何指示它來治療編碼爲Unicode,如果這是正確的措辭?

應用程序引擎有關python 2.5

回答

21

StringIO documentation運行:

不同於由StringIO的模塊實現的存儲器文件,那些由[cStringIO]提供的是不能接受不能被編碼爲Unicode字符串純ASCII字符串。

如果可能,請使用StringIO而不是cStringIO。

+1

我切換(cStringIO是爲了更好的性能),它沒有拋出錯誤,但打印'£'而不是'£'。 爲什麼''現在出現? – rutherford 2009-11-30 03:41:30

+4

''是0xc2 0xa3的Windows-1252解碼,它是u'£'的UTF-8編碼。也許你的終端,應用或無論你看到的是爲Windows-1252而不是UTF-8配置的。 – Phil 2009-11-30 03:48:54

+0

hmm。基本上我正在通過Chrome瀏覽器查看網絡服務器響應。那會是問題嗎? – rutherford 2009-11-30 03:53:02

36

您可以將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) 
+1

此外,由'cStringIO.StringIO()'返回的類文件對象在'with'語句中不起作用,但'codecs.StreamReaderWriter()'返回的包裝器不會! – steveha 2015-10-16 22:07:20

+0

這聽起來類似於https://stackoverflow.com/q/45101658/562769 - 你知道我的問題的答案嗎? – 2017-07-14 11:26:05

3

你也可以將它添加到StringIO的

之前手動編碼您的字符串爲UTF-8
for val in rows: 
    if isinstance(val, unicode): 
     val = val.encode('utf-8') 
result.writelines(rows) 
+2

使用'isinstance'而不是'type is X' – chown 2015-08-08 00:53:44

0

Python 2.6引入了io模塊,您應該考慮使用io.StringIO()「用於unicode文本的內存流」。

在較早的python版本中,這個版本沒有優化(純Python),在後來的版本中這個版本已經被優化爲(快速的)C代碼。