python2编码一直是个老大难的问题,其中包含的内容纷繁复杂,这里也只是针对我项目遇到的问题。为了加深印象,在这里写一个python2.x的编码总结。
首先推荐两篇文章:
http://jackyrong.iteye.com/blog/2404902
https://www.cnblogs.com/franknihao/p/6557559.html
两篇对编码基础和编码会遇到的问题都有很好的讲解。所以一些基础性的知识我就不再记录,下面主要讲我遇到的问题。
问题:我使用requests的时候,得到了如下的unicode string
s = u'\xe4\xbd\xa0\xe5\xa5\xbd'
我期望得到的中文字符,于是不断使用encode与decode,但始终无法解决。
这里s中包含了非常规的unicode元素(常规unicode:u'\u4f60'),我认为对s进行encode,则会先在unicode字符表中寻找对应的字符(unicode是两个字节的编码规范,本例中每两个十六进制(\xe4\xbd)就被当作一个unicode),再对此字符以指定的方式encode。这里存在的问题就是,s中的十六进制数字并不对应unicode编码准则中正确的字符,所以必然不会成功。
解决方法:python提供了一个特殊的编码(raw_unicode_escape)用来处理这种情况,使用s = s.encode('raw_unicode_escape'),就能得到s='\xe4\xbd\xa0\xe5\xa5\xbd'
,再进行编码转换就可得到中文字符。
以下是对编码的一些小结:
python2默认编码是ascii,意味着.py文件中的str及.py文件都是以ascii码来存储(中文是不支持的),在文件头加上# -*- coding:utf-8 -*-,就指定了str和.py文件都以utf-8来编码(支持中文)。
但文件与print打印的编码却并没有遵循utf-8,print obj实际上是调用了sys.stdout.write(obj+'\n'),sys.stdout.encoding 与 locale.getdefaultlocale 在终端上是相同的,即print的编码遵循终端编码。
print sys.getdefaultencoding() #系统默认编码
print sys.getfilesystemencoding() #文件系统编码
print locale.getdefaultlocale() #系统当前编码
print sys.stdin.encoding #终端输入编码
print sys.stdout.encoding #终端输出编码