连接时的Unicode解码错误
我有一个包含一些字符串的列表(大部分是我从sqlite3数据库中获取的):
stats_list = ['Statistik \xc3\xb6ver s\xc3\xa5nger\n', 'Antal\tS\xc3\xa5ng', '1\tCarola - Betlehems Stj\xc3\xa4rna', '\n\nStatistik \xc3\xb6ver datak\xc3\xa4llor\n', 'K\xc3\xa4lla\tAntal', 'MANUAL\t1', '\n\nStatistik \xc3\xb6ver \xc3\xb6nskare\n', 'Antal\tId', u'1\tNiclas']
当我尝试用以下方式连接它时:
return '\n'.join(stats_list)
我遇到了这个错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)
仅仅通过查看这个列表,有没有办法找出为什么会发生这个错误?如果我遍历这个列表并打印出来,我得到的是:
Statistik över sånger Antal Sång 1 Carola - Betlehems Stjärna Statistik över datakällor Källa Antal MANUAL 1 Statistik över önskare Antal Id 1 Niclas
这正是我所期待的,并且没有显示错误。(这些特殊字符是瑞典语的)。
编辑:
我尝试了这个:
return '\n'.join(i.decode('utf8') for i in stats_list)
但它返回了:
Traceback (most recent call last):
File "./CyberJukebox.py", line 489, in on_stats_to_clipboard
stats = self.jbox.get_stats()
File "/home/nine/dev/python/CyberJukebox/jukebox.py", line 235, in get_stats
return self._stats.get_string()
File "/home/nine/dev/python/CyberJukebox/jukebox.py", line 59, in get_string
return '\n'.join(i.decode('utf8') for i in stats_list)
File "/home/nine/dev/python/CyberJukebox/jukebox.py", line 59, in <genexpr>
return '\n'.join(i.decode('utf8') for i in stats_list)
File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 10: ordinal not in range(128)
编辑 2:
建议的解决方案在解释器中对我有效。但当我执行代码时,它却不工作。我搞不懂这是为什么。也许我遗漏了什么明显的东西,所以我把整个方法贴在这里:
def get_string(self):
stats_list = [u'Statistik över sånger\n', u'Antal\tSång']
stats = sorted([(v, k) for k, v in self.song_stats.iteritems()], reverse=True)
for row in stats:
line = '%s\t%s' % row
stats_list.append(line)
stats_list.append(u'\n\nStatistik över datakällor\n')
stats_list.append(u'Källa\tAntal')
stats = sorted([(k, v) for k, v in self.exts_stats.iteritems()])
for row in stats:
line = '%s\t%s' % row
stats_list.append(line)
stats_list.append(u'\n\nStatistik över önskare\n')
stats_list.append(u'Antal\tId')
stats = sorted([(v, k) for k, v in self.wisher_stats.iteritems() if k != ''], reverse=True)
for row in stats:
line = '%s\t%s' % row
stats_list.append(line)
return '\n'.join(i.decode('utf8') for i in stats_list)
song_stats
、exts_stats
和wisher_stats
都是这个类中的字典。
3 个回答
Python 报错说它无法把字符串 'Statistik \xc3\xb6ver s\xc3\xa5nger\n'
转换成 ASCII 字符串。你可以试着在所有的 UNICODE 字符串前面加上 u
。
stats_list = [u'Statistik \xc3\xb6ver s\xc3\xa5nger\n', u'Antal\tS\xc3\xa5ng', u'1\tCarola - Betlehems Stj\xc3\xa4rna', u'\n\nStatistik \xc3\xb6ver datak\xc3\xa4llor\n', u'K\xc3\xa4lla\tAntal', u'MANUAL\t1', u'\n\nStatistik \xc3\xb6ver \xc3\xb6nskare\n', u'Antal\tId', u'1\tNiclas']
这些字符串是用UTF-8编码的。你需要用.decode
把它们转换成unicode
格式:
>>> 'Statistik \xc3\xb6ver s\xc3\xa5nger\n'.decode('utf-8')
u'Statistik \xf6ver s\xe5nger\n'
>>> print _
Statistik över sånger
可以使用列表推导式来对所有元素进行这个操作:
return '\n'.join(x.decode('utf-8') for x in stats_list)
你的问题可能是因为你把unicode字符串和字节字符串混在一起了。
在“编辑2”的代码中,有几个unicode字符串被添加到stats_list
里:
stats_list = [u'Statistik över sånger\n', u'Antal\tSång']
如果你尝试对这些unicode字符串进行解码,你会遇到UnicodeEncodeError
错误。这是因为Python会先尝试用默认的编码(通常是“ascii”)来编码这些字符串,然后再尝试解码。实际上,只有对字节字符串进行解码才是有意义的。
所以,首先把函数最后一行改成:
return '\n'.join(stats_list)
接下来,你需要检查一下其他添加到stats_list
中的字符串是否是字节字符串,并确保它们在转换成unicode字符串之前被正确解码。
所以在这三行代码后面加上print type(line)
,像这样:
line = '%s\t%s' % row
然后每当它打印出<type 'str'>
时,把后面的那一行改成:
stats_list.append(line.decode('utf-8'))
当然,如果它打印出<type 'unicode'>
,那么后面的那一行就不需要改了。
一个更好的解决办法是检查一下字典song_stats
、exts_stats
和wisher_stats
是怎么创建的,确保它们始终包含unicode字符串(或者只包含ascii字符的字节字符串)。