Python编码问题(unicode)

1 投票
3 回答
1023 浏览
提问于 2025-04-16 21:38

在你们开始批评之前,让我先解释一下我的问题(我已经先看过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 个回答

1

看起来虽然你把MySql设置成了UTF-8格式,但实际上你并没有往里面写UTF-8的数据。在把字符串发送之前,你需要先把Unicode编码转换成UTF-8格式。

1

u"My string t\xf4t" 是一个Unicode字符串(它的类型是 unicode),而 "My string t\xf4t" 是一个字节字符串(它的类型是 str)。

unicode(storedInDB, "utf_8") 尝试把字节字符串按照UTF-8格式解码,但 "My string t\xf4t" 不是有效的UTF-8格式。

1

你可能想做的事情是,在你的 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 了。

撰写回答