我有这样的功能:
def convert_to_unicode(data):
row = {}
if data == None:
return data
try:
for key, val in data.items():
if isinstance(val, str):
row[key] = unicode(val.decode('utf8'))
else:
row[key] = val
return row
except Exception, ex:
log.debug(ex)
我将一行结果集(使用MySQLdb.cursors.DictCursor
)逐行输入以将所有字符串值转换为unicode(示例{'column_1':'XXX'}
变为{'column_1':u'XXX'}
)。
问题是其中一行的值类似于{'column_1':'Gabriel García Márquez'}
并且它不会被改变。它抛出了这个错误:
'utf8' codec can't decode byte 0xed in position 12: invalid continuation byte
当我搜索这个时,似乎这与ascii编码有关。
我尝试的解决方案是:
在我的文件开头添加# -*- coding: utf-8 -*-
...没有帮助
将行row[key] = unicode(val.decode('utf8'))
更改为row[key] = unicode(val.decode('utf8', 'ignore'))
...按预期忽略非ascii字符并返回{'column_1':u'Gabriel Garca Mrquez'}
将行row[key] = unicode(val.decode('utf8'))
更改为row[key] = unicode(val.decode('latin-1'))
...是否有工作,但我担心它只支持西欧字符(根据Here)
请有人指出我正确的方向。
答案 0 :(得分:3)
首先:
您在结果集中获得的数据显然是latin-1
编码的,或者您不会观察到此行为。 完全正确试图解码latin-1
编码的字节字符串,好像它是utf-8
- 编码在你脸上爆炸。一旦你有latin-1
编码的字节字符串foo
,如果你想将它转换为unicode类型,foo.decode('latin1')
是正确的做法。
我注意到代码中的unicode(val.decode('utf8'))
表达式。这相当于val.decode('utf8')
;调用字节字符串的.decode
方法将其转换为unicode,因此您在unicode字符串上调用unicode()
,该字符串只返回unicode字符串。
其次:
latin-1
编码支持的字符集中没有包含的字符 - 本身并不是Python的字符串类型,那么多和MySQLdb库一样。我不太了解这个问题,但据我所知,在古代版本的MySQL中,MySQL数据库使用的默认编码是latin-1
,但现在它是utf-8
(和已经很多年了)。但是,默认情况下,MySQLdb库会与数据库建立latin-1
- 编码连接。有几十个与MySQL,Python和字符串编码相关的StackOverflow问题,虽然我不完全理解它们,但对于所有这些似乎对人们有用的问题,一个易于使用的解决方案就是这样:
http://www.dasprids.de/blog/2007/12/17/python-mysqldb-and-utf-8 我希望我能就MySQLdb问题给你一个更全面,更自信的答案,但我从来没有使用过MySQL,也不想冒任何不真实的风险。也许有人可以来并提供更多细节。尽管如此,我希望这可以帮助你。
答案 1 :(得分:2)
您的第三个解决方案 - 将编码更改为"latin-1"
- 是正确的。您的输入数据被编码为Latin-1,因此您必须将其解码为。除非有人在某处做了非常愚蠢的事情,否则输入数据不可能包含该编码的无效字符。