python编码问题初探


主要涉及到的因素:文件编码,python解析器版本,在IDLE下print语句和直接显示的输出差异



一、python 2.x



如果你用的是2.x版本的python,那么能在IDLE中正常输出的编码是ASCII ,GBK(GB2312),Unicode。如果你想在IDLE解释器中正常显示字符,那么编码必须是三者之一,另外python 2.x中默认的编码是GBK,即你在IDLE中输入的中文字符默认的编码是GBK。



如果你正在处理文件,并想文件中的中文能在IDLE正常显示,我们来看看应该怎么处理:

python3设置显示编码_字符串

 


注意右下角的文件编码是GBK,此时我们读取文件内容并显示:


python3设置显示编码_python3设置显示编码_02

 



可以看到不需作任何处理,输出的内容是正常的。



下面看看当文件编码是UTF8时,IDLE的表现:


python3设置显示编码_字符串_03

 


测试代码如下:


python3设置显示编码_python3设置显示编码_04

 




代码中,第一行的输出为直接print字符串,可以看到内容为乱码


第二行是用字符串的decode方法将字符串用UTF8解码成Unicode字符,此时字符串可以正常输出


第三行是将字符串解码后再用gbk编码,此时字符串亦能正常输出



Tips:


1.在不改变IDLE的环境设置时,IDLE中的汉字的编码默认都是GBK。


2.不要把IDLE中的字符串和从文件中读取的字符串放在同一个print语句中混合输出。


3.py代码中中文字符的编码和py文件的编码一致,即源文件编码是GBK,那么其中汉字的编码为GBK,源文件编码是UTF8,那么其中汉字的编码为UTF8



下面在来说一下在python2.x中输出的一个很奇怪的现象,如下图:


python3设置显示编码_编码_05

 


在IDLE中,a是一个中文字符串,b是一个包含a的列表


直接在IDLE中输入a时,显示的是字符串a的数据格式,即GBK编码下的存储的实际数据


而print a时,这是解释器会把数据转换成一个容易理解的形式,中文显示出来


而在处理b这个包含中文字符串的列表时,print并没有这么智能地将GBK的编码转换成汉字。这是正常的情况,它只是程序的输出,并不会影响程序的运行(判断中文字符串是否相等,以及一些其他的字符串操作),所以不用担心


注:在python中,一切都是对象,对象中的__str__方法控制了对象在被print时的表现,具体可以自己查阅相关书籍


python3设置显示编码_python3设置显示编码_06

 




二、python 3.x的编码表现


python3.x对2做出了巨大的改动,其中一个就是IDLE的默认编码改为UTF8。


在python3.x下很多显示的问题消失了:


python3设置显示编码_字符串_07

 



可以发现完全没问题



另外在处理文件时,python3.x的open函数支持在打开文件时指定编码(默认打开的编码是GBK ==!),如下:处理UTF8编码:


python3设置显示编码_python3设置显示编码_08

 



处理GBK编码:


python3设置显示编码_文件编码_09

 




另外值得注意的是,在3.x中,py文件的编码只能保存成utf8编码,GBK是非法的!



三、爬虫中的编码问题


最近很多鱼油在玩高端的爬虫,其中可能涉及到很多乱码问题。下面稍微提下如何判断爬下来的网页编码,以2.x为例:


python3设置显示编码_文件编码_10

 



如图,服务器在response的headers里面会指出返回内容的类型以及编码。如果编码不是你想要的,那么恭喜你,需要作一些编解码的转换来满足你的应用需求。另外你可能碰到gzip的压缩编码,那么需要用gzip的相关函数来解压缩。


大多数服务器都能根据用户在请求头构造的请求编码来返回相应编码的内容,这样就需要你自己来构造请求头,下面如下:


python3设置显示编码_编码_11