本文转载于: https://www.cnblogs.com/schut/p/8407258.html
阅读本文前,可以先阅读前一篇文章《Python 常见字符编码介绍》。
编码的转换
虽然有了 unicode 和 utf-8,但由于历史问题,各个国家依然在大量使用自己的编码,比如中国的 windows ,默认编码依然是 gbk ,而不是 utf-8 。基于此,如果中国的软件出口到美国,美国人的电脑上就会显示乱码,因为他们没有 gbk 编码。
所以,该怎么办呢?
unicode 还有一个功能,是其包含了跟全球所有国家编码的映射关系,这时就派上用场了。无论你什么编码存储的数据,只要你的软件在把数据从硬盘读到内存里,转成 unicode 来显示就可以了。由于所有系统、编程语言都默认支持 unicode ,那你的 gbk 软件放到美国电脑上,加载到内存里,变成了 unicode ,中文就可以正常显示了。
Python 经常以 utf-8 来编码,之所以能在 windows gbk 的终端显示正常,是因为到了内存里, python 解释器把 utf-8 lfn dn b unicode.
Python3 执行过程
(1)解释器找到代码文件,把代码字符串按文件头定义的编码加载到内存,转成 unicode。
(2)把代码字符串按照语法规则进行解释。
(3)所有的变量字符都会以 unicode 编码声明。
python2 在内存里默认编码不是 unicode,而是 ASCII ,想写中文,就必须声明文件的 coding 为 gbk 或者 utf-8 ,声明之后,python2 解释器仅以文件头声明的编码去解释你的代码,加载到内存后,并不会主动帮你转为 unicode,也就是说,你的文件编码是 utf-8 ,加载到内存里,你的变量字符串也是 utf-8 , 意味着,你以 utf-8 编码的文件,在 windows 是乱码。
所以,我们只好手动转了,python3 自动把文件编码转为 unicode 必定是调用了什么方法,这个方法就是 decode()(解码),和 encode() (编码)。
UTF-8/GBK --> decode() --> Unicode
Unicode --> encode() --> GBK/UTF-8
s = '匆匆'
print(s) # py2 输出乱码,py3输出“勿勿”
s1 = s.decode("utf-8") # utf-8 转成 Unicode,decode(解码)需要注明当前编码格式
print(s1,type(s1)) # 先decode为 unicode 输出 (u'\u5306\u5306', <type 'unicode'>)
# 此时 s1是unicode类型,可以将它encode成显示器可显示的编码显示出来
print("s1: {}".format(s1.encode("gbk"))) # 再 encode 转码为 gbk 显示在显示器上 s1: 匆匆
print("s1 type:{}".format(type(s1))) # s1 type:<type 'unicode'> str.encode()会生成新的str 对象,不会影响原来的str
s2 = s1.encode("gbk") # unicode 转成 gbk,encode(pyEncode)需要注明生成的编码格式
print(s2, type(s2))
s3 = s1.encode("utf-8") # unicode 转成 utf-8,encode(pyEncode)注明生成的编码格式
print(s3, type(s3))
#coding:utf-8
s = "你好,中国!"
print(s) # Python2输出乱码,Python3正常输出
print(type(s)) # 均输出 <type 'str'>
#解码成unicode
s1 = s.decode("utf-8")
print(s1) # Python2中输出 “你好,中国!”,Python3显示'str'对象没有属性'decode'
print(type(s1)) # Python2中输出 <type 'unicode'> Python3中输出 <class 'str'>
#编码成gbk 或 utf-8
s2 = s1.encode('gbk')
print(s2) # Python2中输出 “你好,中国!”
print(type(s2)) # Python2中输出 <type 'str'>
s3 = s1.encode('utf-8')
print(s3) # Python2输出乱码,
print(type(s3)) # 输出 <type 'str'>
总结1:
Decode 的作用是将其他编码的字符串转换成 unicode 编码,如 s.decode("utf-8"),表示将 utf-8 的字符串s转换成 unicode 编码
Encode 的作用是将 unicode 编码转换成其他编码的字符串,如 s.encode("utf-8"), 表示将 unicode 的字符串s转换成 utf-8 编码
在做编码时,通常需要以 unicode 作为中间编码,即先装饰其他编码的字符串解码(decode)成 unicode ,再从 unicode 编码(encode)成另一种编码。
总结2:
python3 文件默认编码是utf-8 , 字符串编码是 unicode 以utf-8 或者 gbk等编码的代码,加载到内存,会自动转为unicode正常显示。
python2 文件默认编码是 ascii , 字符串编码也是 ascii , 如果文件头声明了是 gbk,那字符串编码就是 gbk。以 utf-8 或者 gbk等编码的代码,加载到内存,并不会转为 unicode ,编码仍然是 utf-8 或者 gbk 等编码。