谈谈 Python 3 的字符串编码问题

python的字符串编码一直是一个超级大的坑。

突然想起来谈这个是因为昨天有一个简单的操作困扰了我很久,解决之后决定写点东西。

具体步骤是:

  • 使用pymysql从数据库中读取一张表。
  • 使用json.dumps将数据打成字符串。
  • 将字符串输出到文件保存。

简单操作之后发现文件中保存的值全是类似与\uffff之类的unicode码值。

在一番调试之后,我发现,直接从表中拿出的数据是dist格式的,而json在使用dumps方法的时候会把dist中的unicode字符转成unicode的码值。dumps有一个参数ensure_ascii,这个值默认为True,所以在压缩字符串时会将unicode码转成码值,所以我们使用dumps压缩包含unicode的dict时需要手动修改参数。

text = json.dumps(data,ensure_ascii=False)

调试之后,输出的结果正常。

接下来就是把字符串输出到文件,这里我们把str格式的字符通过write()方法写入文件后,又变成了乱码。

这里我们简单分析一下python3的字符串机制。

python3中的字符可以简单的分为字节流和字符串。

python3移除了python2的unicode字符串设定,所有的字符串都是unicode编码。

但是为什么我们写入到文件之后又变成了乱码呢。

我们知道写入操作实际上是把字符串解码成字节流写入文件的。而unicode编码的字符串在写入时会按照unicode的编码方式解码成字节流并写入。

如果目标系统的默认编码是GBK或者ascll之类的,那么他就会将unicode的字节流当作GBK编码来编码显示。

例如,我有一个unicode格式的字符串”中文”,那么写入文件的时候,实际上写入的字节流为\u4e2d\u6587,而如果当前平台的编码为GBK,那么在显示的时候,他就会把这个字节流以GBK的格式解码,最后显示出来的就自然而然是乱码了。

所以,如果你想正常的写入中文到文件的话。

  • 第一步是查看目标平台的编码格式。
  • 第二步是确定你准备写入的数据是unicode格式(当然,python3中只要是str格式就一定是unicode)。
  • 第三步,将数据encode成目标平台编码格式的字节流。
  • 第四步,打开文件时使用wb或者rb模式打开,将准备好的字节流写入。

这样,打开文件后,中文就可以正常的显示了。

举个例子。如果我有一个utf-8编码的文件,系统是GBK编码我该怎么让他正常显示?

  • 读取字节流,decode(“utf8”)变为python3字符串
  • encode(“GBK”)变为GBK字节流。
  • 写入字节流即可。

现在知道怎么解决github的readme文件的中文乱码问题了么。

发表评论

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据