python基础4 ----字符编码

时间:2023-03-09 01:53:54
python基础4 ----字符编码

python基础---字符编码

  一、了解字符编码

    1. 文本编辑器存取文件的原理(nodepad++,pycharm,word)

        打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编写的内容也都是存放与内存中的,断电后数据丢失

因而需要保存到硬盘上,点击保存按钮,就从内存中把数据刷到了硬盘上。

在这一点上,我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,都只是在编写一堆字符而已。

2. python解释器执行py文件的原理 ,例如python test.py

        第一阶段:python解释器启动,此时就相当于启动了一个文本编辑器

        第二阶段:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中

        第三阶段:python解释器解释执行刚刚加载到内存中test.py的代码

  总结:

  1. python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样。
  2. 与文本编辑器不一样的地方在于,python解释器不仅可以读文件内容,还可以执行文件内容。

二、字符编码的发展史

  1、字符翻译成数字的过程就是一个字符如何对应一个特定数字的标准,这个标准称之为字符编码

  2阶段一:现代计算机起源于美国,最早诞生也是基于英文考虑的ASCII(其范围之适用于英文)

  ASCII:一个Bytes代表一个字符(英文字符/键盘上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1种变化,即可以表示256个字符。ASCII最初只用了后七位,127个数字,已经完全能够代表键盘上所有的字符了(英文字符/键盘的所有其他字符),后来为了将拉丁文也编码进了ASCII表,将最高位也占用了

  3、阶段二:为了满足中文,中国人定制了GBK (GBK:2Bytes代表一个字符)。

      日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里。

 4、阶段三:各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。于是产生了unicode,统一用2Bytes代表一个字  符,2**16-1=65535,可代表6万多个字符,因而兼容万国语言,但对于通篇都是英文的文本来说,这种编码方式无疑是多了一倍的存储空间(二进制最终都是以电或者   磁的方式存储到存储介质中的)于是产生了UTF-8,对英文字符只用1Bytes表示,对中文字符用3Bytes。

  补充:

  1. 内存中使用的编码是unicode,用空间换时间(程序都需要加载到内存才能运行,因而内存应该是尽可能的保证快)
  2. 硬盘中或者网络传输用utf-8,网络I/O延迟或磁盘I/O延迟要远大与utf-8的转换延迟,而且I/O应该是尽可能地节省带宽,保证数据传输的稳定性

  三、字符编码的使用

  1、乱码产生的原因

    文件从内存刷到硬盘的操作简称存文件,文件从硬盘读到内存的操作简称读文件。

    乱码一:存文件时就已经乱码

    存文件时,由于文件内有各个国家的文字,我们单以shiftjis去存,本质上其他国家的文字由于在shiftjis中没有找到对应关系而导致存储失败,用open函数的write可以测试,f=open('a.txt','w',encodig='shift_jis'),f.write('你瞅啥\n何を見て\n') #'你瞅啥'因为在shiftjis中没有找到对应关系而无法保存成功,只存'何を見て\n'可以成功,但当我们用文件编辑器去存的时候,编辑器会帮我们做转换,保证中文也能用shiftjis存储(硬存,必然乱码),这就导致了,存文件阶段就已经发生乱码,此时当我们用shiftjis打开文件时,日文可以正常显示,而中文则乱码了。

    乱码二:存文件时不乱码而读文件时乱码

    存文件时用utf-8编码,保证兼容万国,不会乱码,而读文件时选择了错误的解码方式,比如gbk,则在读阶段发生乱码,读阶段发生乱码是可以解决的,选对正确的解码方式就ok了,而存文件时乱码,则是一种数据的损坏。

  2、解决办法:

    核心法则就是,文件以什么编码保存的,就以什么编码方式打开

  四、分析python程序的执行过程

    1、过程

      阶段一:启动python解释器

      阶段二:python解释器此时就是一个文本编辑器,负责打开文件test.py,即从硬盘中读取test.py的内容到内存中。此时,python解释器会读取test.py的第一行内 容,#coding:utf-8,来决定以什么编码格式来读入内存,这一行就是来设定python解释器这个软件的编码使用的编码格式是这个编码。可以用sys.getdefaultencoding()查 看,如果不在python文件指定头信息#-*-coding:utf-8-*-,那就使用默认的python2中默认使用ascii,python3中默认使用utf-8

      阶段三:读取已经加载到内存的代码(unicode编码的二进制),然后执行,执行过程中可能会开辟新的内存空间,比如x="egon"

    注释:内存的编码使用unicode,不代表内存中全都是unicode编码的二进制,在程序执行之前,内存中确实都是unicode编码的二进制,比如从文件中读取了一行x="egon",其中的x,等号,引号,地位都一样,都是普通字符而已,都是以unicode编码的二进制形式存放与内存中的,但是程序在执行过程中,会申请内存(与程序代码所存在的内存是俩个空间),可以存放任意编码格式的数据,比如x="egon",会被python解释器识别为字符串,会申请内存空间来存放"egon",然后让x指向该内存地址,此时新申请的该内存地址保存也是unicode编码的egon,如果代码换成x="egon".encode('utf-8'),那么新申请的内存空间里存放的就是utf-8编码的字符串egon了.

    五、python2与python3的区别

    1、在python2中有两种字符串类型str和unicode

    str类型:当python解释器执行到产生字符串的代码时(例如s='林'),会申请新的内存地址,然后将'林'encode转移成文件开头指定的编码格式,这已经是encode之后的结果了,所以s只能decode

    unicode类型:当python解释器执行到产生字符串的代码时(例如s=u'林'),会申请新的内存地址,然后将'林'以unicode的格式存放到新的内存空间中,所以s只能encode,不能decode

    2、 在python三种也有两种字符串类型str和bytes