在使用Python编写程序过程中,我们经常需要向文件或者是向终端打印日志,这时大家经常遇到的一个问题就是中文输出的乱码问题。造成乱码的根本原因就是程序文件的编码与打印终端的编码格式不一致。下面我们通过一个简单的例子说明一下。
我
们写一个最简单的Python程序log.py,打印”你好“两个字。首先,我们设置程序文件的编码格式是UTF-8。这时我们进入WIndows
CMD窗口,运行python log.py,可以看出输出乱码。这时因为我们程序里使用的是UTF-8编码,而Windows
CMD终端默认使用的是CP936(也就是GB2312B编码),两者编码不一致,因此导致了乱码。见下面两幅图中红框部分。
解决问题的方法很简单,可以将log.py文件的编码转为GB2312格式,这样就可以正常的打印“你好”两个字了。如下图所示。
通过手工修改编码的方式当然可以解决问题,但是当程序文件很多时,修改起来非常的麻烦,尤其容易造成遗漏。此外,如果程序拿到另外一台电脑运行,一旦该电脑默认的字符集发生改变,那么乱码问题又将产生。
那
么有没有一种可以较好的自动化解决乱码问题的方法呢,从而尽量减少人工的操作。答案是肯定的:就是利用程序自动的识别终端的编码以及程序中需要打印的字符
串的编码,然后将字符串的编码转为和终端一致的编码就可以了。对于终端的编码可以通过Python内置的sys模块的
sys.stdout.encoding获得。而获得程序中使用的字符串的编码,就要用到下面我们将要介绍的chardet模块了。
利用chardet模块,我们将刚才的程序作简要的修改.。
import chardet #引入chardet模块
import sys #引入sys模块
text = "你好"
orig_encoding = chardet.detect(text)['encoding'] #获得字符串编码格式
term_encoding = sys.stdout.encoding #获得终端编码格式
print text.decode(orig_encoding).encode(term_encoding )#将字符串编码转换
由于chardet.detect输出的是一个字典,因此我们通过键值"encoding"获得探测的字符串的编码。这里需要强调的是chardet探
测的编码结果不一定百分之百正确,但是通常都是不会出错的。将程序修改后,我们再次运行第一个测试,输出结果如下,可以看出程序正确打印了我们需要的结
果。