前戏
从今天开始我们就要学习文件相关的知识了,讲到文件的话有一种文件叫文本文件。文本文件涉及到了字符及字符概念,说到字符就必须考虑字符编码了,所以在讲文件之前必须了解字符编码。
字符编码从字面的意思上看肯定会和字符有关系,也就是说但凡涉及得到字符的地方就一定会有字符编码的应用。
跟字符有关系的地方一者是由字符组成的文本文件;二者就是在python语法中的 定义字符串 的语法,字符串这种数据类型也会涉及得到字符编码的问题。
字符编码其实也没多少用武之地,但它的理论、讲究非常多,对于咱们这种开发人员来讲我们只需要记住他最终的结论就可以了,就好比我们需要做图片处理工作的时候经常会直接使用PIL模块,而不是一点儿一点儿地去写出来一个类似于PIL的n个函数。如果你不懂结论的话,你会很难记住它,也就是说我们在讲字符编码之前要了解三个重要的知识点。
这第一点就和运行程序有关,计算机三大核心硬件:cpu、内存、硬盘。就这三大核心来讲,咱们的所有代码最开始都是要存放到硬盘中的程序的运行是由硬盘加载给内存的,也就是说任何软件的启动都是把数据从硬盘读入内存然后才开始运行的。程序运行过程中产生的数据都是要先寄存到内存当中的。
拿PyCharm举个例子,放到平时它就是一个文本编译器,它无非就是功能多点儿而已。如果说我们在文件中敲代码,那么代码是不是就是它运行过程中产生的数据。当我们保存之后这些数据就会写入硬盘,这样文本就保存下来了。
再看第二个知识点:文本编辑器读取文件的三个步骤。第一步就是启动文本编辑器,从硬盘加载到内存,然后cpu来执行它内存里的代码,这样文本编辑器就这样启动起来了;第二步,假设我们想要编辑一个已有文件,我们应该打开该文件,这个短暂的过程又发生了什么呢?其实就是文本编辑器会将文件内容从硬盘读入到内存,文本编辑器会把刚刚的数据为你展示到屏幕上。而我们使用的python解释器执行python文件的流程其实就与这个过程十分相似。
最后是这第三个知识点:运行python程序的步骤。第一阶段就是启动python解释器把解释器的代码从硬盘读到内存,然后再由cpu执行,这样python解释器就启动起来了,这就相当于是启动了一个文本编译器;第二阶段里它会把硬盘里的python文件内容读入内存,这时候内存里就有两种程序了,一种是由官方用C语言完成的python解释器、一种是我们用python语言编写的python程序;我们再看第三阶段。它不再会想文本编译器那样把内容打印在屏幕上了,而是将里面的内容当成python的语法开始识别,识别你定义的变量、识别你定义的if判断、识别你的for循环等等。这就是python解释器与python文件的区别。所以说咱们写python文件的后缀名不管改成什么都没关系,你把它改成mp4都没问题,只要里面的内容是符合python语法的就可以运行:
现在我们思考一下python解释器执行的python文件分为三个阶段,到底哪些阶段涉及了字符编码的概念?有兴趣的初学者朋友们可以在评论区里打出来。
字符编码
我们在写代码的时候用的都是人类能够读懂的字符,比如中文、英文等等。但是计算机只能识别二进制数,它本身是基于电工作的,电又有高电平和低电平两种特性人类从逻辑层面将高电平对应的数字对应为1,则低电平为0。也就是说这一抉择决定了计算机只能识别0、1这两个数字。所以我们写的字符到计算机能识别的二进制数必须有一个翻译的过程,这个过程也必须有一个特定的标准,这个标准就是“字符编码表”。字符编码表上存放的都是字符和数字一一对应的关系,只要我们写的字符能都与这种关系对应上再将其转化为二进制就方便多了。
如果我们将“刘”这个字打在一个python文件里,这时候它是会报错的。如果我们将“刘”与100这串数字对应上那么我再打一个“刘”字它就会将100这个数字输出(纯学术假设)。这时候我们就非常明确了:字符编码表的关系是一个字符对一个数字的关系,十分简单,简单到我们自己都能够设计,当然,计算机才不认可我们设计的呢,包括刚才的那个刘字。字符编码表的作用就是把字符集中的字符编码为指定集合中某一对象。
其实大家读完以上内容之后就会发现:“摩斯电码”和“字符编码表”真是有异曲同工之妙呀!
懂了字符编码表的作用之后我们就来思考一个问题:如果我在文件里打了一个“刘”字,请问一共发生了几件事?有兴趣的初学者朋友们可以在评论区里打出来。
提示:有的朋友们家里的电脑配置低、装的软件多,当他打完字后字一秒或几秒后才会出现,这段时间电脑在干嘛呢?
ASCII码表
字符编码表的发展可以用一句话概括,那就是“分久必合,合久必分”
由于现代计算机的起源是美国,他们当时并没有考虑过其他国家也需要电脑,所以他们仅仅是把英文字符以及各种符号和数字建立了联系,于是就有了最早的“ASII码表”,他的全称是“American Standard Code for Informaation Interchage” ( 美国信息接口标准规范 )。
现在有一个问题:如果让我们来设计ASCII码表的话我们会用几位二进制数来对应一个字母呢?如果我们只用一位二进制数来对应的话行不通,一位二进制数字一个能对应0,一个能对应1如果我们用两位二进制数就有4种变化了:01、11、10、00,这样就可以对应四个英文字符,很明显两位二进制数也不够。现在我们的出了一个结论:只要我们增加二进制的位数能够对应的字符也就越多。所以最终的ASII码表采用的是八进制数来对应一个字符。
GBK编码
上面我们简单地介绍了一下ASCII码表,现在假设我们就处于那个时代,只有ASCII码表,作为一个计算机使用者我是不能够在电脑敲打中文字符,因为ASCII码表里面根本就没有中文的对照关系,我们就只能敲英文字符,我们敲得英文字符首先是转成ASCII码表里对应的二进制数然后存到内存当中,但是内存里的数据一旦断电就会立马丢失掉了,所以我们如果想永久保存的话就要存到硬盘里,现在内存里存的是二进制,当然我们存硬盘里也得是存为二进制格式,所以直接把内存里的二进制数据放到硬盘里去就行了。
现在我们要打开这个硬盘里的文件,那就是把这个二进制数据读到内存,然后再参考ASCII码表把这个二进制数据反理解成对应的字符,文件就打开了。这个时候没有乱码出现是没问题的,也不可能有乱码的问题,因为这时候是ASCII码表一统天下的,紧接着咱们Chinese看到了,我们就把美国人的数据买了过来,但买过来以后发现不行呀,我买了你的计算机我只能敲英文字符,中文字符不能写也太难受了!怎么办呢?毫无疑问的是ASCII码表的标准不继续能在计算机里作为唯一的标准来使用了,我们得换一种标准了。
有了以上的背景以后伟大的Chinese就开始定制自己的标准了,而这个标准就是GBK。GBK其实也很简单,也是字符和数字之间的对应关系,只是增加了中文字符,比ASCII码表长了亿点而已。但是这个时候如果我们继续采用8位2进制数来对应一个字符明显就不够了,说历史那是上下五千年,说数据那是近100000(十万)汉字,八位只能显示256个数中文字符这么多,256连才不过是常用汉字的九牛一毛,即使到了现在连很多复杂的生僻字也打不出来。
如果说8位不够用就照前面说的呗 — 加数位。最后一直加到了16位,而2的16次方就是65536。其实世界上人们所使用的字符并没有我们想象的那么多。比如说日本,在徐福出海、遣唐使来华的时候学习、借鉴、简化了我们的许多文化,汉语和日语其实也有很多相似之处,比如说这个“女”字,日语中也有,只是所表达的意思不同而已,所以说世界上5561种字符中很大一部分都是一样的。65536,这么大个数字容纳常用汉字还是绰绰有余的。
由于8位二进制数足以表示英文字符的所以GBK仍可以保持用二进制数来表示英文字符、用16位二进制数表示中文字符,如果都保持统一英文字符也用16位二进制数的话其实是对内存空间的一种浪费因为你的英文字符根本用不到16位,所以英文前面都是用0占着位置都就太浪费了。
unicode编码
1988年,有几位程序员在开发国际化程序的时候,对于不同国家的字符在不同的计算机上不兼容的问题实在忍无可忍了,于是他们就开源了unicode项目,其目的就是为了开发出一套支持全世界的字符集。1989年,ISO(国际标准化组织)也发布了UCS字符草案,后来unicode与UCS意识到世界上不需要两套统一的字符集,于是两者开始进行兼容性合并。他们从1990年开始研发,1994年正式发布,这就是unicode编码的由来,我们也称之为万国码。这个编码和咱们中国的GBK编码一样,仍然采用16位二进制数对应一个字符,只不过那时候咱们的GBK只是编码罢了。
我们常说的8位16位指的就是比特位,1bit就是1位二进制数,注意:这里的b是小写的b,然后8个bit就是1个Bytess,这个B就是大写的B了,Bytess我们又称之为字节,而1KB(1000B)也就是1024字节,1MB等于10241024KB,1GB等于1024MB,1TB等于1024GB.以上的这些都是以1024为单位计算的。不然为什么程序员节会定在10月24日、C站会有那么多关于1024的勋章呢。当然,技术界的圈子里还有一个梗,如果有人向某位业内人士借1000块钱,那这个圈内人人一定会借给他1024块钱,而那二十四块钱他的解释肯定是凑个整数,这位借钱的肯定把那心里藏着的问号尽数写在了脸上。这就是一个梗而已,仅供大家消遣,别总以为我是什么圈内人士。
但是做硬盘的厂家计算硬盘容量却都是以1000来计算的,所以我们购买的500G的硬盘的实际容量只有460多G。电信运营商计算网速是以比特计算的,它们的单位叫Mbps(兆比特/秒),意思是每秒传输二进制数位的数量。而我们常说的下载速度是MBps(兆字节/秒),这里要区别一下b的大小写,它这里指的是每秒传输的字节数量。上面我们也说了:一个字节等于八个比特位,所以我们用的100兆的宽带实际的下载速度是要除以八的,看来实际的下载速度还真是大打折扣,也就是12兆多一点点的样子,就这个恐怕还是排除干扰后的最理想状态,实际多情况下是根本达不到这个速度的。
由于1个字节等于8个比特位,所以我们会说unicode里面是用两个字节表示一个中文字符的。如果这个字是个较为复杂的生僻字甚至可能需要4个字节、8个字节来表示。而对于现在的计算机来讲所有国家的人而言,他们都可以在同一台计算机里面输入自己国家的文字了,真可谓是“千里共婵娟”呀!
💕Final~
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,bye~