Python编码问题(unicode)
在你们开始批评之前,让我先解释一下我的问题(我已经先看过Python的unicode文档了)。
我使用json模块把一个json格式的结果解析成字典。这会给我一些unicode编码的字符串(比如:u"My string t\xf4t")。然后我用Mysqldb把这个字符串存储到我的Mysql数据库里。我想说明一下,这个数据库是配置成utf8的。
接着,我用MysqlDB取回我的Mysql记录。现在我打印出来的结果看起来是"My string t\xf4t"(没有u)。因为我需要比较插入的字符串和取回的字符串,所以我得告诉Python我取回的字符串是unicode格式的。
不管我尝试什么,我总是遇到UnicodeDecodeError的错误。我试着调整编码:unicode(storedInDB, "utf_8"),还试过错误参数("replace")。但我还是遇到异常。
你们有什么建议吗?
谢谢你们的帮助!
3 个回答
看起来虽然你把MySql设置成了UTF-8格式,但实际上你并没有往里面写UTF-8的数据。在把字符串发送之前,你需要先把Unicode编码转换成UTF-8格式。
u"My string t\xf4t"
是一个Unicode字符串(它的类型是 unicode
),而 "My string t\xf4t"
是一个字节字符串(它的类型是 str
)。
unicode(storedInDB, "utf_8")
尝试把字节字符串按照UTF-8格式解码,但 "My string t\xf4t"
不是有效的UTF-8格式。
你可能想做的事情是,在你的 MySQLdb.connect()
调用中添加 charset='utf8'
。
对于MySQL来说,字符集是在很多不同的地方单独设置的,最明显的就是表的存储和连接(而且不幸的是,MySQL在很多情况下默认使用latin-1)。所以,你可以花时间把整个数据库设置为使用UTF-8:
CREATE DATABASE somedatabase DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
然而,当你连接一个客户端时,MySQL可能仍然认为你用的是其他编码在和它交流:
mysql> show variables like 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
一个基本的解决办法是在连接后立即执行 SET NAMES UTF8
,在你做其他任何事情之前:
mysql> SET NAMES UTF8;
mysql> show variables like 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
不过,在你的情况下,这样做还不够,因为python的MySQLdb模块本身也想帮忙,会自动对python的原生unicode字符串进行编码和解码。所以,你需要在MySQLdb中设置字符集。最好的方法是,如前所述,在创建MySQLdb连接时传递 charset='utf8'
。这样做会让MySQLdb通知mysql服务器你的连接使用的是UTF8,因此你就不需要直接运行 SET NAMES UTF8
了。