一、前言
1、任何一个程序都是先存放与硬盘上的,要想运行起来 必须先由硬盘读取到内存,之后cpu去内存中取指然后执行。
2、在运行的程序产生的数据最先都是存放在内存中的。
3、 计算机是基于电工作的 那么计算机只能识别电信号;
计算机内部存储数据用的都是01010101的二进制数据。
4、文件的后缀名仅仅是给人看的 。因为对应计算机来说所有的数据都是0101010的二进制。
5、普通的文本编辑器和python解释器的工作流程
相同:
1.任何的程序要想运行都是先从硬盘读取到内存
2.文本编辑器和python解释器都会去硬盘中读取你想要读取的文件内容
不同:
3.文本编辑器将文件内容读取之后仅仅是展示给用户看
而我们的python解释器会识别语法并执行python代码
6、字符编码研究的范围只针对文本文件 ,音频、视频这些不包含在内
7、只有文本文件里写的是一堆字符
win系统中以.txt结尾的都是文本文件;wps中更改文件名后缀为.txt后文件就会乱码
8、内存固定使用unicode,可以改的是从内存写入硬盘的格式
9、文件头:控制的是文件读时候的编码(python解释器一横一横读,第一行读到后就会按照文件头的编码类型)
10、如果不知道文件以什么方式存的,就会乱码,除非一遍遍试对了
二、概念
1、字符编码?
字符-------(标准)--------数字
2、字符编码表
存放的是字符与数字的对应关系
三、字符编码的发展史
1、一家独大
计算机起源于美国
美国人用英文交流 但是计算机只能识别二进制数据
为了能够让计算机识别人类能够读懂的字符,这里面肯定有一个
人类字符 >>> 计算机二进制数据
中间的字符与数字的对应关系其实就是一张表
ASCII码表
这张表只记录了英文和数字的对应关系
用8位(bit)来表示一个英文字符
1bytes = 8bit
1024bytes = 1KB
1024KB = 1MB
1024MB = 1GB
1024GB = 1TB
1024TB = 1PB
1024PB = 1EB
ASCII:只能识别英文字符
特点:采用8bit对应一个英文字符
8bit=》1Byte
2、 群雄割据
中国人也用得起计算机
自己做一个汉字跟数字对应关系 GBK
GBK表
汉字、英文 跟数字的对应
1bytes来表示英文
2bytes来表示汉字
如果出现了生僻字可能还需要用3bytes甚至跟多的bytes
GBK:可以识别中文字符串与英文字符
特点:采用16bit对应字符,该字符可以是英文字符、也可以是中文字符
日本人也用得起计算机
自己做一个汉字跟数字对应关系 shift_JIS
shift_JIS表
日文、英文 跟数字的对应
韩国人也用得起计算机
自己做一个汉字跟数字对应关系 Euc_kr
Euc_kr表
韩文、英文 跟数字的对应
我们在输入中文字符的时候
1.内部基于GBK翻译成了对应的二进制数据 在内存
2.然后将基于GBK编码的二进制数据刷到硬盘 永久保存
3.将硬盘中基于GBK编码的二进制数据读取到内存之后按照GBK编码的对应关系翻译成对应的中文
3、天下一统
万国码 unicode
兼容万国
并且跟之前所有国家的编码都有对应关系
1990开始研究的 1994年才开始正式使用
所有的字符都是用2bytes来存储
英文用2bytes
中文也用2bytes
unicode:存在的意义:可以识别万国字符,兼容老的字符
特点:2Bytes对应一个字符
4、为了尽可能的提升写入硬盘的速度,衍生出utf-8(英文全称Unicode Transformation Format)
utf-8
1Byte对应英文字符
3Byte对应一个中文字符
四、总结
1、群雄割据: 英文字符--------------内存:ASCII二进制数--------------->硬盘:ASCII二进制数 中文英文字符--------------内存:GBK二进制数--------------->硬盘:GBK二进制数 日文英文字符--------------内存:shiftJIS二进制数--------------->硬盘:shiftJIS二进制数 韩文英文字符--------------内存:Euc-Kr二进制数--------------->硬盘:Euc-Kr二进制数 2、过渡阶段: 中文英文字符------------内存:unicode=========gbk============>硬盘:GBK二进制数 日文英文字符------------内存:unicode=========shifJIS========>硬盘:shiftJIS二进制数 韩文英文字符------------内存:unicode=========Euc-Kr=========>硬盘:Euc-Kr二进制数 万国字符----------------内存:unicode=========utf-8==========>硬盘:utf-8二进制数 内存固定使用:unicode 我们可以改变的是从内存写入硬盘采用的编码格式 3、分久必合: 万国字符----------------内存:unicode=========utf-8==========>硬盘:utf-8二进制数 万国字符----------------内存:utf-8==========================>硬盘:utf-8二进制数
五、遇到的问题与解决办法
乱码问题: 1、存的时候乱了:采用的字符编码表无法识别输入的字符 存的时候就已经乱了,是无法补救的,取的时候一定也乱了 解决方法:存入硬盘的编码格式应该用utf-8格式 2、存的时候没有乱码:采用的字符编码表可以识别输入的字符 但是取的时候乱码了:采用的字符编码表与当初存的时候用的不是同一张表,可以补救 解决方法:存的时候用什么编码,取的时候一定要用同样的编码格式 与运行python程序有关的乱码问题: 1、保证运行python程序的前两个阶段不乱码 在python文件的开头加一行: #coding:文件存的时候用的编码格式 2、保证第三个阶段不乱码 使用python3 如果使用的是python2,应该在符串前加前缀u
ps:
1、在python3中字符串类型的值在内存中都是unicode格式的数字
2、在python2中字符串类型的值在内存中都是文件头指定编码格式的数字
python2中用的是ASCII码,如果在字符串前加前缀u就把字符串强制存成unicode格式,推荐使用
六、编码&解码
字符对应成数字叫编码
给用户展示的是字符
把数字对应成字符的过程叫解码
字符-----编码--------》unicode格式的数字------编码-----》gbk格式的数字
字符-----解码--------》unicode格式的数字《------解码-----gbk格式的数字
#示范: x = "上" # unicode格式的数字==编码===>其他编码格式的数字 res1=x.encode("gbk") # print(res1,type(res1)) res2=x.encode("utf-8") # print(res2,type(res2)) # bytes类型可以理解为一种硬盘的原生格式,把它当成二进制看 # str类型 # 其他编码格式的数字==解码==>unicode格式数字 x=res1.decode("gbk") # print(x) y=res2.decode("utf-8") print(y,type(y))
七、知识扩充:
首先来说,编码即是密码本,编码记录的就是二进制与文字之间的对应关系,现存的编码本有: ASCII码:包含英文字母,数字,特殊字符与01010101对应关系。 a 01000001 一个字符一个字节表示。 GBK:只包含本国文字(以及英文字母,数字,特殊字符)与0101010对应关系。 a 01000001 ascii码中的字符:一个字符一个字节表示。 中 01001001 01000010 中文:一个字符两个字节表示。 Unicode:包含全世界所有的文字与二进制0101001的对应关系。 a 01000001 01000010 01000011 00000001 b 01000001 01000010 01100011 00000001 中 01001001 01000010 01100011 00000001 UTF-8:包含全世界所有的文字与二进制0101001的对应关系(最少用8位一个字节表示一个字符)。 a 01000001 ascii码中的字符:一个字符一个字节表示。 To 01000001 01000010 (欧洲文字:葡萄牙,西班牙等)一个字符两个字节表示。 中 01001001 01000010 01100011 亚洲文字;一个字符三个字节表示。首先来说,编码即是密码本,编码记录的就是二进制与文字之间的对应关系,现存的编码本有: ASCII码:包含英文字母,数字,特殊字符与01010101对应关系。 a 01000001 一个字符一个字节表示。 GBK:只包含本国文字(以及英文字母,数字,特殊字符)与0101010对应关系。 a 01000001 ascii码中的字符:一个字符一个字节表示。 中 01001001 01000010 中文:一个字符两个字节表示。 Unicode:包含全世界所有的文字与二进制0101001的对应关系。 a 01000001 01000010 01000011 00000001 b 01000001 01000010 01100011 00000001 中 01001001 01000010 01100011 00000001 UTF-8:包含全世界所有的文字与二进制0101001的对应关系(最少用8位一个字节表示一个字符)。 a 01000001 ascii码中的字符:一个字符一个字节表示。 To 01000001 01000010 (欧洲文字:葡萄牙,西班牙等)一个字符两个字节表示。 中 01001001 01000010 01100011 亚洲文字;一个字符三个字节表示。