Python2和Python3的编码区别:
1:什么是字符串编码?
在计算机的世界,所有的数据本质上都由二进制表示
字符串编码:为了让人们能够读懂计算机数据,将计算机里的二进制数据,通过编码表对应,转换为人类可以看懂的字符
编码表历史:
1. 最早的计算机是美国人发明的,最开始设计编码表的时候,只考虑的美国的语言习惯(数据、字母和普通字符)0~127,出现了 ASCII 美国标准信息交换码
2. 后来计算机开始普及全球,由于0~127不够用了,各个国家开始指定自己的编码表(在ASCII表基础上进行扩展,表示前127个都是一样的),便有了欧洲 Latin-1、 中国简体中文 GB2312、繁体中文 Big5、日本Shift_JIS。
3. 由于导致各个国家的编码不统一,文化交流不方便,文本内容传输做编码转换很麻烦。
于是国标组织指定了一个大一统的编码表:Unicode 万国码(给世界上每个字符,单独指定了一个二进制,再通过Unicode编码表转换)
Unicode里每个字符占用4个字节(不够4个字节,前面补0),所以Unicode浪费空间。
'a' == 00000000 00000000 00000000 01100001
4. 于是在Unicode基础上做了升级,UTF-8编码(可变长的Unicode),可以根据字符类型来指定字节空间(尽可能减少空间占用)
在UTF-8里,一个字母1个字节,一个汉字3个字节 ; 在GBK里,一个字母1个字节,一个汉字2个字节(在简体中文处理GBK优于UTF-8)
5. UTF-8 也是当前世界上最流行的编码表处理方案,所有的Linux终端默认编码是UTF-8, 90%的网页都是UTF-8,简体中文的Windows终端默认编码是 GBK,也称为 CP936 (code page 936)
*乱码是指:显示指定编码的字符时,使用了其他的编码表(如简体中文Windows终端默认使用BGK编码,强行显示utf-8字符串是就会出现乱码)
2:python 字符串类型 和 编码 的关系?
python2 的字符串类型 和编码:
str 类型 是非Unicode编码(GBK,utf-8,jpg,mp4)
Unicode 类型字符串是Unicode编码
python3 的字符串类型和编码:
str类型字符串是Unicode编码
bytes 类型字符串是非Unicode编码(GBK,utf-8,jpg,mp4,mp3)
*3: 字符串编码转换
定律:任何操作系统、任何编程语言、任何编码字符串,都可以和Unicode互相转换。
例如:utf-8字符串转为GBK字符串
1. 任何编码的字符串,都可以通过decode 解码为 Unicode字符串
unicode_str = utf8_str.decode("utf-8")
2. Unicode字符串,可以通过 encode 编码为 指定编码字符串
gbk_str = unicode_str.encode("gbk")
反之亦然:
unicode_str = gbk_str.decode("gbk")
utf8_str = unicode_str.encode("utf-8")
4:python解释器终端创建的字符串编码
python2的终端创建字符串,Windows是GBK编码,Linux是UTF-8编码(为str类型,非unicode编码)
ipython2里创建的字符串,统一为utf-8编码
python3的终端创建字符串,默认都是Unicode编码,为str类型(Unicode编码)
ipython3里创建的字符串,统一为Uncode编码
5:字符串默认写unicode 到文件的编码方式
**默认解释器编码:python2->ascii,python3->utf-8
Python3:
用 w 模式写入一个unicode字符串,保存到文件时,默认按解释器编码 (utf-8)进行编码转换,再写入文件中,所以文件编码是utf-8
import sys
sys.getdefaultencoding() # 查看当前Python3默认解释器编码,为utf-8
with open("test.txt", "w") as f:
f.write(unicode_str)
Python2:
import sys
sys.getdefaultencoding() # 查看当前Python2默认解释器编码,为ascii
用 w 模式写入一个unicode字符串,保存到文件时,默认按解释器编码 (ascii)进行编码转换,如果字符串里有中文等非ascii字符,无法将Unicode 按 ascii 编码处理,就会报出 UnicodeEncodeError
with open("test.txt", "w") as f:
f.write(unicode_str)
解决方案
1:将Python2的解释器编码,转为和Python3 一样的 utf-8
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
**字符串默认写Unicode到文件的方式(手动转码 、 文件encoding),可以不通过解释器编码转换处理(重点):
Python3:
1. 手动对字符串进行编码转换,wb 模式再写入文件
with open("test.txt", "wb") as f:
f.write(unicode_str.encode("gbk"))
2. 通过 open() 方法的 encoding 参数指定编码写入:
with opne("test.txt", "w", encoding="gbk") as f:
f.write(unicode_str)
Python2:
1. 手动对字符串进行编码转换,wb/w 模式再写入文件
with open("test2.txt", "wb") as f:
f.write(unicode_str.encode("gbk"))
2. 通过 codecs.open() 方法的 encoding 参数指定编码写入:
import codecs
with codecs.open("test.txt", "w", encoding="gbk") as f:
f.write(unicode_str)
总结:python写入Unicode字符串到文件时,指定编码方案:
手动对Unicode字符串编码转换为非Unicode字符串,再写入非Unicode字符串
通过 open()方法的encoding参数指定编码,再写入Unicode字符串
如果没有手动编码也没有指定编码,则默认通过 解释器编码 默认转码处理,自动转码再写入文件
6:文件编码
当写入一个字符串到文件时,文件编码等于该字符串的编码。
如果写入了一个其他编码的字符串,会导致文件内容有乱码,而且无法得知之前的内容是什么。
注意:不要在同一个文件中,写入不同的编码字符串。
7:网页编码
/html/head/meta/charset 指定了该网页的字符编码
8:python代码文件头部申明
Python3 默认是 utf-8
Python2 默认是 ascii
所有需要手动指定为 utf-8
#coding:urf-8