day10_编码

转载  https://zhuanlan.zhihu.com/p/108805502

3.4 utf-8的由来

注意:如果保存到硬盘的是GBK格式二进制,当初用户输入的字符只能是中文或英文,同理如果保存到硬盘的是Shift_JIS格式二进制,当初用户输入的字符只能是日文或英文……如果我们输入的字符中包含多国字符,那么该如何处理?

#多国字符—√—》内存(unicode格式的二进制)——X—》硬盘(GBK格式的二进制)

#多国字符—√—》内存(unicode格式的二进制)——X—》硬盘(Shift_JIS格式的二进制)

#多国字符—√—》内存(unicode格式的二进制)——√—》硬盘(???格式的二进制)

理论上是可以将内存中unicode格式的二进制直接存放于硬盘中的,但由于unicode固定使用两个字节来存储一个字符,如果多国字符中包含大量的英文字符时,使用unicode格式存放会额外占用一倍空间(英文字符其实只需要用一个字节存放即可),然而空间占用并不是最致命的问题,最致命地是当我们由内存写入硬盘时会额外耗费一倍的时间,所以将内存中的unicode二进制写入硬盘或者基于网络传输时必须将其转换成一种精简的格式,这种格式即utf-8(全称Unicode Transformation Format,即unicode的转换格式)

# 多国字符—√—》内存(unicode格式的二进制)——√—》硬盘(utf-8格式的二进制

那为何在内存中不直接使用utf-8呢?

utf-8是针对Unicode的可变长度字符编码:一个英文字符占1Bytes,一个中文字符占3Bytes,生僻字用更多的Bytes存储

unicode更像是一个过渡版本,我们新开发的软件或文件存入硬盘都采用utf-8格式,等过去几十年,所有老编码的文件
 

4.2 python解释器执行文件的前两个阶段

执行py文件的前两个阶段就是python解释器读文本文件的过程,与文本编辑读文本文件的前两个阶段没人任何区别,要保证读不乱码,则必须将python解释器读文件时采用的编码方式设置为文件当初写入硬盘时的编码格式,如果没有设置,python解释器则才用默认的编码方式,在python3中默认为utf-8,在python2中默认为ASCII,我们可以通过指定文件头来修改默认的编码

  • 在文件首行写入包含#号在内的以下内容
# coding: 当初文件写入硬盘时采用的编码格式

解释器会先用默认的编码方式读取文件的首行内容,由于首行是纯英文组成,而任何编码方式都可以识别英文字符。

 

4.3 python解释器执行文件的第三个阶段

设置文件头的作用是保证运行python程序的前两个阶段不乱码,经过前两个阶段后py文件的内容都会以unicode格式存放于内存中。

在经历第三个阶段时开始识别python语法,当遇到特定的语法name = '上'(代码本身也都全都是unicode格式存的)时,需要申请内存空间来存储字符串'上',这就又涉及到应该以什么编码存储‘上’的问题了。

在Python3中,字符串类的值都是使用unicode格式来存储

由于Python2的盛行是早于unicode的,因此在Python2中是按照文件头指定的编码来存储字符串类型的值的(如果文件头中没有指定编码,那么解释器会按照它自己默认的编码方式来存储‘上’),所以,这就有可能导致乱码问题

python2后推出了一种补救措施,就是在字符串类型前加u,则会将字符串类型强制存储unicode,这就与python3保持一致了,对于unicode格式无论丢给任何终端进行打印,都可以直接对应字符不会出现乱码问题

 

三大核心硬件

所有软件都是运行硬件之上的,与运行软件相关的三大核心硬件为cpu、内存、硬盘,我们需要明确三点



#1、软件运行前,软件的代码及其相关数据都是存放于硬盘中的 #2、任何软件的启动都是将数据从硬盘中读入内存,然后cpu从内存中取出指令并执行 #3、软件运行过程中产生的数据最先都是存放于内存中的,若想永久保存软件产生的数据,则需要将数据由内存

 

2.2 文本编辑器读取文件内容的流程

#阶段1、启动一个文件编辑器(文本编辑器如nodepad++,pycharm,word)

#阶段2、文件编辑器会将文件内容从硬盘读入内存

#阶段3、文本编辑器会将刚刚读入内存中的内容显示到屏幕上

2.3 python解释器执行文件的流程

以python test.py为例,执行流程如下

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

#阶段2、python解释器相当于文本编辑器,从硬盘上将test.py的内容读入到内存中

#阶段3、python解释器解释执行刚刚读入的内存的内容,开始识别python语法

毫无疑问,由人类的字符到计算机中的数字,必须经历一个过程,如下

翻译的过程必须参照一个特定的标准,该标准称之为字符编码表,该表上存放的就是字符与数字一一对应的关系。

字符编码中的编码指的是翻译或者转换的意思,即将人能理解的字符翻译成计算机能识别的数字

 

 ASCII表的特点:
    1、只有英文字符与数字的一一对应关系
    2、一个英文字符对应1Bytes1Bytes=8bit8bit最多包含256个数字,可以对应256个字符,足够表示所有英文字符

为了让计算机能够识别中文和英文,中国人定制了GBK

# GBK表的特点:
    1、只有中文字符、英文字符与数字的一一对应关系
    2、一个英文字符对应1Bytes
       一个中文字符对应2Bytes   
       补充说明:
       1Bytes=8bit8bit最多包含256个数字,可以对应256个字符,足够表示所有英文字符
       2Bytes=16bit16bit最多包含65536个数字,可以对应65536个字符,足够表示所有中文字符

每个国家都各自的字符,为让计算机能够识别自己国家的字符外加英文字符,各个国家都制定了自己的字符编码表

 

1中,文本编辑存取文件的原理如下

文本文件内容全都为字符,无论存取都是涉及到字符编码问题
#1、存文本文件
人类通过文本编辑器输入的字符会被转化成ASCII格式的二进制存放于内存中,如果需要永久保存,则直接将内存中的ASCII格式的二进制写入硬盘

#2、读文本文件
直接将硬盘中的ASCII格式的二进制读入内存,然后通过ASCII表反解成英文字符

unicode于1990年开始研发,1994年正式公布,具备两大特点:

#1. 存在所有语言中的所有字符与数字的一一对应关系,即兼容万国字符

#2. 与传统的字符编码的二进制数都有对应关系,详解如下

很多地方或老的系统、应用软件仍会采用各种各样传统的编码,这是历史遗留问题。此处需要强调:软件是存放于硬盘的,而运行软件是要将软件加载到内存的,面对硬盘中存放的各种传统编码的软件,想让我们的计算机能够将它们全都正常运行而不出现乱码,内存中必须有一种兼容万国的编码,并且该编码需要与其他编码有相对应的映射/转换关系,这就是unicode的第二大特点产生的缘由

文本编辑器输入任何字符都是最新存在于内存中,是unicode编码的,存放于硬盘中,则可以转换成任意其他编码,只要该编码可以支持相应的字符

# 英文字符可以被ASCII识别
英文字符--->unciode格式的数字--->ASCII格式的数字

# 中文字符、英文字符可以被GBK识别
中文字符、英文字符--->unicode格式的数字--->gbk格式的数字

# 日文字符、英文字符可以被shift-JIS识别
日文字符、英文字符--->unicode格式的数字--->shift-JIS格式的数字

3.3 编码与解码

由字符转换成内存中的unicode,以及由unicode转换成其他编码的过程,都称为编码encode

由内存中的unicode转换成字符,以及由其他编码转换成unicode的过程,都称为解码decode

在诸多文件类型中,只有文本文件的内存是由字符组成的,因而文本文件的存取也涉及到字符编码的问题

 集合总结

 


# 1.2、去重


# 2、定义: 在{}内用逗号分隔开多个元素,多个元素满足以下三个条件
#            1. 集合内元素必须为不可变类型
#            2. 集合内元素无序
#            3. 集合内元素没有重复

#
1、作用 # 1.1 关系运算 # friends1 = ["zero","kevin","jason","egon"] # friends2 = ["Jy","ricky","jason","egon"] # # l=[] # for x in friends1: # if x in friends2: # l.append(x) # print(l) # s={1,2} # s=set({1,2}) # s={1,[1,2]} # 集合内元素必须为不可变类型 # s={1,'a.txt','z','b',4,7} # 集合内元素无序 # s={1,1,1,1,1,1,'a.txt','b'} # 集合内元素没有重复 # print(s) # 了解 # s={} # 默认是空字典 # print(type(s)) # 定义空集合 # s=set() # print(s,type(s)) # 3、类型转换 # set({1,2,3}) # res=set('hellolllll') #将字符串先按照空格分隔,再去重;变为,不可变,无序,且去重的 集合 # print(res) # print(set([1,1,1,1,1,1])) # print(set([1,1,1,1,1,1,[11,222]]) # 报错 # print(set({'k1':1,'k2':2})) # 4、内置方法 # =========================关系运算符========================= friends1 = {"zero","kevin","jason","egon"} friends2 = {"Jy","ricky","jason","egon"} # 4.1 取交集:两者共同的好友 # res=friends1 & friends2 # print(res) # print(friends1.intersection(friends2)) # 4.2 取并集/合集:两者所有的好友 # print(friends1 | friends2) # print(friends1.union(friends2)) # 4.3 取差集:取friends1独有的好友 # print(friends1 - friends2) # print(friends1.difference(friends2)) # 取friends2独有好友 # print(friends2 - friends1) # print(friends2.difference(friends1)) # 4.4 对称差集: 求两个用户独有的好友们(即去掉共有的好友) # print(friends1 ^ friends2) # print(friends1.symmetric_difference(friends2)) # 4.5 父子集:包含的关系 # s1={1,2,3} # s2={1,2,4} # 不存在包含关系,下面比较均为False # print(s1 > s2) # print(s1 < s2) # s1={1,2,3} # s2={1,2} # print(s1 > s2) # 当s1大于或等于s2时,才能说是s1是s2他爹 # print(s1.issuperset(s2)) # print(s2.issubset(s1)) # s2 < s2 =>True # s1={1,2,3} # s2={1,2,3} # print(s1 == s2) # s1与s2互为父子 # print(s1.issuperset(s2)) # print(s2.issuperset(s1)) # =========================去重========================= # 1、只能针对不可变类型去重,,若是包含可变类型则报错 unhashable type: 'list' # print(set([1,1,1,1,2])) # 2、无法保证原来的顺序, # l=[1,'a.txt','b','z',1,1,1,2] # l=list(set(l)) # print(l) l=[ {'name':'lili','age':18,'sex':'male'}, {'name':'jack','age':73,'sex':'male'}, {'name':'tom','age':20,'sex':'female'}, {'name':'lili','age':18,'sex':'male'}, {'name':'lili','age':18,'sex':'male'}, ] new_l=[] for dic in l: if dic not in new_l: new_l.append(dic) # print(new_l) # 其他操作 ''' # 1.长度 >>> s={'a.txt','b','c'} >>> len(s) 3 # 2.成员运算 >>> 'c' in s True # 3.循环 >>> for item in s: ... print(item) ... c a.txt b ''' # 其他内置方法 s={1,2,3} # 需要掌握的内置方法1:discard # s.discard(4) # 删除元素不存在do nothing # print(s) # s.remove(4) # 删除元素不存在则报错 # 需要掌握的内置方法2:update # s.update({1,3,5}) # print(s) # 需要掌握的内置方法3:pop # res=s.pop() # print(res) # 需要掌握的内置方法4:add # s.add(4) # print(s) # 其余方法全为了解 res=s.isdisjoint({3,4,5,6}) # 两个集合完全独立、没有共同部分,返回True print(res) # 了解 # s.difference_update({3,4,5}) # s=s.difference({3,4,5}) # print(s)

 

posted @ 2021-03-28 16:01  walkerpython  阅读(60)  评论(0编辑  收藏  举报