一、知识储备
1、三大核心硬件——CPU,内存,硬盘
所有软件都是运行硬件之上的,与运行软件相关的三大核心硬件为cpu、内存、硬盘
#1、软件运行前,软件的代码及其相关数据都是存放于硬盘中的
#2、任何软件的启动都是将数据从硬盘中读入内存,然后cpu从内存中取出指令并执行
#3、软件运行过程中产生的数据最先都是存放于内存中的,若想永久保存软件产生的数据,则需要将数据由内存写入硬盘
2、文本编辑器读取文件内容的流程
#阶段1、启动一个文件编辑器(文本编辑器如nodepad++,pycharm,word)
#阶段2、文件编辑器会将文件内容从硬盘读入内存
#阶段3、文本编辑器会将刚刚读入内存中的内容显示到屏幕上
3、Python解释器执行文件的流程
以python test.py为例,执行流程如下:
#阶段1、启动python解释器,此时就相当于启动了一个文本编辑器
#阶段2、python解释器相当于文本编辑器,从硬盘上将test.py的内容读入到内存中
#阶段3、python解释器解释执行刚刚读入的内存的内容,开始识别python语法
4、总结—Python解释器&文本编辑器的异同
#1、相同点:
前两个阶段二者完全一致,都是将硬盘中文件的内容读入内存,详解如下 python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样
#2、不同点:
在阶段3时,针对内存中读入的内容处理方式不同,详解如下——
文本编辑器将文件内容读入内存后,是为了显示或者编辑,根本不去理会python的语法,而python解释器将文件内容读入内存后,可不是为了给你瞅一眼python代码写的啥,而是为了执行python代码、会识别python语法)
二、字符编码
1、什么是字符编码
人类在与计算机交互时,用的都是人类能读懂的字符,如中文字符、英文字符、日文字符等 而计算机只能识别二进制数。
解释如下:
二进制数即由0和1组成的数字,例如 010010101010。
计算机是基于电工作的,电的特性即高低电平,
人类从逻辑层面将高电平对应为数字1,低电平对应为数字0,
这直接决定了计算机可以识别的是由0和1组成的数字
由人类的字符到计算机中的数字,必须经历一个过程:
翻译的过程必须参照一个特定的标准,该标准称之为字符编码表,
该表上存放的就是字符与数字一 一对应的关系。
字符编码中的编码指的是翻译或者转换的意思,即将人能理解的字符翻译成计算机能识别的数字
2、字符编码表的发展史 (了解)
字符编码的发展经历了三个重要的阶段——
2.1 阶段一:一枝独秀——ASCII(american standard code for information interchange,美国信息交换标准代码)
现代计算机起源于美国,所以最先考虑仅仅是让计算机识别英文字符,于是诞生了ascii表
ascii第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,共定义了128个字符。
# ascii表的特点: 1、只有英文字符与数字的一一对应关系 2、一个英文字符对应1bytes,1bytes=8bit,8bit最多包含256个数字, 可以对应256个字符,足够表示所有英文字符
2.2 阶段二:百花齐放,百家争鸣——GBK,Shift_JIS,Euc-kr
为了让计算机能够识别中文和英文,中国人定制了GBK
# gbk表的特点:
1、只有中文字符、英文字符与数字的一一对应关系
2、一个英文字符对应1bytes 一个中文字符对应2bytes
补充说明:
1bytes=8bit,8bit最多包含256个数字,可以对应256个字符,足够表示所有英文字符
2bytes=16bit,16bit最多包含65536个数字,可以对应65536个字符,足够表示所有中文字符
每个国家都各自的字符,为让计算机能够识别自己国家的字符外加英文字符,各个国家都制定了自己的字符编码表:
# 日本——Shift_JIS表的特点:
1、只有日文字符、英文字符与数字的一一对应关系
# 韩国——Euc-kr表的特点:
1、只有韩文字符、英文字符与数字的一一对应关系
此时——
美国人用的计算机里使用字符编码标准是ascii、
中国人用的计算机里使用字符编码标准是gbk、
日本人用的计算机里使用字符编码标准是shift_jis,如下图所示:
文本编辑存取文件的原理如下:
文本文件内容全都为字符,无论存取都是涉及到字符编码问题 #1、存文本文件 人类通过文本编辑器输入的字符会被转化成ASCII格式的二进制存放于内存中,如果需要永久保存,则直接将内存中的ASCII格式的二进制写入硬盘 #2、读文本文件 直接将硬盘中的ASCII格式的二进制读入内存,然后通过ASCII表反解成英文字符
不同国家的字符编码标准不同,只支持本国语言以及英文,但是若一台美国电脑想要存储日文文件,就无法识别,出现乱码。
2.3 阶段三:和谐统一 ——unicode
unicode码扩展自ascii字元集。是一个编码方案,unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
unicode 编码共有三种具体实现,分别为utf-8,utf-16,utf-32,其中utf-8占用一到四个字节,utf-16占用二或四个字节,utf-32占用四个字节。unicode 码在全球范围的信息交换领域均有广泛的应用。
unicode于1990年开始研发,1994年正式公布,具备两大特点:
#1. 存在所有语言中的所有字符与数字的一一对应关系,即兼容万国字符
#2. 与传统的字符编码的二进制数都有对应关系
文本编辑器输入任何字符都是最先存在于内存中,使用的是unicode编码,存放于硬盘中,
则可以转换成任意其他编码,只要该编码可以支持相应的字符。
# 英文字符可以被ascii识别
英文字符--->unciode格式的数字--->ascii格式的数字
# 中文字符、英文字符可以被gbk识别
中文字符、英文字符--->unicode格式的数字--->gbk格式的数字
# 日文字符、英文字符可以被shift-jis识别
日文字符、英文字符--->unicode格式的数字--->shift-jis格式的数字
3、编码与解码
3.1 由字符转换成内存中的unicode,以及由unicode转换成其他编码的过程,都称为编码encode
3.2 由内存中的unicode转换成字符,以及由其他编码转换成unicode的过程,都称为解码decode
在诸多文件类型中,只有文本文件的内存是由字符组成的,因而文本文件的存取也涉及到字符编码的问题
4、utf-8的由来
如果保存到硬盘的是gbk格式二进制,当初用户输入的字符只能是中文或英文,
同理如果保存到硬盘的是shift_jis格式二进制,当初用户输入的字符只能是日文或英文
如果是多国字符混杂的文件,该用什么格式的二进制 存入硬盘呢?
理论上是可以将内存中unicode格式的二进制直接存放于硬盘中的,但有两大缺点——
=1=更费空间
由于unicode固定使用两个字节来存储一个字符,如果多国字符中包含大量的英文字符时,使用unicode格式存放会额外占用一倍空间(英文字符其实只需要用一个字节存放即可)
=2=更耗时间
空间占用并不是最致命的问题,最致命地是当我们由内存写入硬盘时会额外耗费一倍的时间
所以将内存中的unicode二进制写入硬盘或者基于网络传输时必须将其转换成一种精简的格式,
这种格式即utf-8(全称unicode transformation format,即unicode的转换格式)
那为何在内存中不直接使用utf-8呢?
utf-8是针对Unicode的可变长度字符编码:一个英文字符占1Bytes,一个中文字符占3Bytes,生僻字用更多的Bytes存储
unicode更像是一个过渡版本,我们新开发的软件或文件存入硬盘都采用utf-8格式,
等过去几十年,所有老编码的文件都淘汰掉之后,会出现一个令人开心的场景——
即 硬盘里放的都是utf-8格式,此时unicode便可以退出历史舞台,内存里也改用utf-8
三、字符编码的应用
前面一大串的铺垫,只为了解决这个问题——为了存取字符时不发生乱码问题
#1、内存中固定使用unicode无论输入任何字符都不会发生乱码
#2、我们能够修改的是存/取硬盘的编码方式,如果编码设置不正确将会出现乱码问题。
乱码问题分为两种:存乱了,读乱了
#2.1 存乱了:
如果用户输入的内容中包含中文和日文字符,如果单纯以shift_jis存,日文可以正常写入硬盘,而由于中文字符在shift_jis中没有找到对应关系而导致存乱了
#2.2 读乱了:
如果硬盘中的数据是shift_jis格式存储的,采gbk格式读入内存就读乱了
因此:
#1. 保证存的时候不乱:在由内存写入硬盘时,必须将编码格式设置为支持所输入字符的编码格式
#2. 保证读的时候不乱:在由硬盘读入内存时,必须采用与写入硬盘时相同的编码格式
3.1 文本编辑器nodpad++存取文本文件
文本编辑器存取的都是文本文件,而文本文件中包含的内容全为字符,所以存取文本文件都涉及到字符编码的问题。
3.2 python解释器执行文件
Python3中,特殊情况比如输入字符串,默认的设置就能保住不乱码。
第一阶段——读取文件到硬盘
第二阶段——在内存里默认直接存为Unicode
第三阶段——读文件,硬盘里默认使用utf-8存储,读取到内存后转为Unicode
但是如果事先指定了存文件的编码(比如:gbk),怎么保证第三个阶段读文件时不乱码——修改文件头,为一开始指定的编码即可:
#coding:gbk
Python2中,
=保证Python程序前两个阶段不乱码的方法——
避免读取文件乱码的现象: 先搞清楚 文件存的时候用的是什么编码,读的时候就要用什么编码。
文件头:在文件开头声明存文件时使用的编码,让Python解释器不要再使用默认的编码(Python3—默认utf-8;Python2—默认ASCII)来读文件,而是用文件头声明的编码—— 例如,存代码时,使用的是gbk编码,则在文件第一行声明
#coding:gbk
=保证第三阶段不乱码—— 输入字符串,记得加小u
x=u'上' print(x)
3.3 字符串encode编码与decode解码的使用
# 1、unicode格式------编码encode-------->其它编码格式
>>> x='上' # 在python3在'上'被存成unicode
>>> res=x.encode('utf-8')
>>> res,type(res) # unicode编码成了utf-8格式,而编码的结果为bytes类型,可以当作直接当作二进制去使用 (b'\xe4\xb8\x8a', <class 'bytes'>)
# 2、其它编码格式------解码decode-------->unicode格式
>>> res.decode('utf-8')
参考资料:
https://zhuanlan.zhihu.com/p/108805502
来源:https://www.cnblogs.com/bigorangecc/p/12468345.html