Python: Chracter Encoding

 7th March 2019 at 9:00am

Python 的编码问题,Fluent Python 第四章 有非常不错的解答,解释了编码问题的深层原因,以及解决办法。

History of default encoding

这篇博文解释了 Python 编码设计的一些历史原因: Why sys.setdefaultencoding() will break code。这篇文章的内容感觉比较水,我在这里总结一下。

2000 年时,Python 的开发者们决定给还未发布的 Python 2.0 增加 Unicode 相关的特性(Unicode Aware Python),于是有了 unicodestr 两种类型。但是当时互联网还未流行,很多国家甚至都没有多少计算机人才,所以编码问题在当时还是一个泥潭。同时当时 UTF-8 还没有成为编码格式中的标准。于是 Python 的开发者们选择了 ascii 作为 unicodestr 间隐式转换的编码,所以 sys.getdefaultencoding() 函数会返回 ascii

但是他们犯了一个错误,提供了 sys.setdefaultencoding() 函数供开发者修改默认编码,这使得很多依赖于默认编码为 ascii 的程序出错。于是它们决定修复这个错误,用一种比较 hacky 的方式,在 path.py 初始化完后,删除了 sys.setdefaultencoding()

但是随时时间推移,UTF-8 成了编码界的事实标准,大量的数据都使用了 UTF-8。于是默认的 ascii 编码很容易出现编解码问题。于是一种 reload hack 流行了起来:

import sys
reload(sys)
sys.setdefaultencoding('utf8')

这种方式可以简单粗暴地解决一些问题,使得它很受欢迎。但是它仍然会引起一些其他库类出错,所以不受 Python 官方推荐。

后来 Python 3 将默认的编码改为了 UTF-8,并且去除了 byte string (str in py2) 和 text string (unicode in py2) 之间的隐式转换。于是 Python 2 中编解码出错的问题得到了比较好地解决。