Python2中的编码涉及到以下几个方面:
1、编辑器的编码方式
2、运行python的终端编码方式
3、sys.getdefaultencoding()获取的编码方式
4、头部声明的:# coding: utf-8
首先,不论用户输入什么字符,在硬盘、内存中都是二进制。
"我"这个中文的utf-8编码为:\xe6\x88\x91,gbk编码为:\xce\xd2
一、编辑器编码
在PyCharm中,文件的默认编码方式为utf-8,也就是说,在PyCharm中编码的python代码,最终会以utf-8编码后存储到硬盘上。
在PyCharm中创建一个test.py文件,内容如下:
a = '我'
通过Hex Editor软件以只读方式打开这个test.py后,可以看到其在硬盘上存储的二进制如下:
当然,可以在PyCharm中设置默认编码不为utf-8,方式为:File -> Settings -> Editor -> File Encodings -> Global Encoding。
所以,编辑器的编码作用就是将文件内容以编辑器指定的编码存储到硬盘上。
二、头部声明的编码
我们都知道,Python2中不能使用中文,如果要使用,需要在头部加上声明:
# coding: utf-8
a = '我'
如果我们不加这个编码,直接在终端运行test.py文件,会出现这样一个错误:
Python解释器是一个进程,进程在执行时,需要将test.py的文件内容读取到内存中执行。而python解释器会默认以ascii编码的方式来解释代码,当文件出现"我"的utf-8编码的第一个字节\xe6时,ascii是无法识别的,因此直接会报语法错误。
而在头部声明了编码方式为utf-8,此时解释器会以utf-8编码来解释代码。这样在文件编码和解释器编码一致的情况下就不会出现这种问题。
当然,如果你将默认编码方式改成gbk,再次运行,还是会报语法错误,不过这次它的提示是gbk无法解码:
因此,需要保证文件的存储编码方式和程序头部声明的编码方式一致。
三、运行Python程序的终端编码
将我们的test.py文件内容加上一行,此时文件内容为:
# coding: utf-8
a = '我'
print(a)
在PyCharm中运行,输出结果为:
在windows自带的cmd窗口执行:
可以看到,相同的代码,在不同的环境下执行的结果竟然不一样。。。
当程序中出现print
这种将字符打印出来的代码时,会将字节解码成unicode,然后找到对应的字符显示,在解码的过程中,使用的解码方式为终端的默认编码。
windows自带的cmd默认编码为GBK。。。
在Linux终端,默认的编码方式为UTF-8
四、sys.getdefaultencoding获取的编码
通常,即使我们在程序头部声明了编码方式为utf-8,再通过sys.getdefaultencoding()返回的编码仍然是ascii编码。。。。
这个函数获取的编码有什么作用呢,其实就是给一些内置的函数设定的默认编码,例如:encode()、decode()、unicode()这些没有指明编码方式时候,就会通过sys.getdefaultencoding()获取到的编码来进行转换。
我们的测试程序代码如下:
# coding: utf-8
a = '我'
a.decode()
运行时会直接报错:
可以看到,又是说ascii不能解码。。。
我们可以通过setdefaultencoding()方法来对这些函数的默认编码进行设置:
# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
a = '我'
print a.decode()
再次运行,就可以看到正常输出结果了。
五、其它
在python2中,可能遇到一种情况,打印出来的列表或者字典出现Unicode码,类似下面这样:
源程序如下:
# coding: utf-8
a = [u'\\u4f60']
print a
这时候可以遍历这个列表,然后对每个Unicode以unicode-escape
的方式解码,每解一次,可以去掉一个\
线(python源码中\用来转义下一个\,因此实际只有一个反斜线):
# coding: utf-8
a = [u'\\u4f60']
print a
for i in a:
print i.decode('unicode-escape')
这时候再运行,就可以得到我们想要的结果了。