再谈编码
1、小数据池
2.、is和==的区别
3、编码的问题
一、小数据池:
1、代码块:python程序是由代码块构成的,一个代码块的文件作为python程序执行
的单元,
代码块:一个模板,一个函数,一个类,甚至是一个command命令都是一个代码块,一个文件也是
# 一个代码块,eval()、exec()执行的时候也是一个代码块
小数据池:是一种驻留机制,各大编程语言中都有类似的东西,在网上搜索常量池,小数据池也是值
的都是同一个内容。
小数据池只针对:整数、字符串、布尔值、其他类型不存在驻留机制。
二、is 和 = 的区别:
is: 判断两边内容存储地址是否一致,如果返回True,那两个变量是同一对象(判断的结果是cmd控制台结果)
=:判断两边的值是否相等。
我们可以这样认为内存地址相同,则值一定相等。值相等内存地址不一定相等。
在python中对-5到256之间的整数会被驻留在内存中. 将一定规则的字符串缓存. 在使用
的时候, 内存中只会创建一个该数据的对象. 保存在小数据池中. 当使用的时候直接从小数据
池中获取对象的内存引用. 而不需要创建一个新的数据. 这样会节省更多的内存区域.
优点: 能够提高一些字符串, 整数的处理速度. 省略的创建对象的过程.
缺点: 在'池'中创建或者插入新的内容会花费更多的时间.
对于数字: -5~256是会被加到小数据池中的. 每次使用都是同一个对象.
对于字符串:
1. 如果字符串的长度是0或者1, 都会默认进行缓存
2. 字符串长度小于1, 但是字符串中只包含字母, 数字, 下划线时才会缓存
3. 用乘法的到的字符串. ①. 乘数为1, 仅包含数字, 字母, 下划线时会被缓存. 如果
包含其他字符, 而长度<=1 也会被驻存, ②. 乘数小于1 . 仅包含数字, 字母, 下划
线这个时候会被缓存. 但字符串长度不能小于20
4. 指定驻留. 我们可以通过sys模块中的intern()函数来指定要驻留的内容.
OK. 到目前为止. 我们已经了解了python的小数据池的一些基本情况了.
最后一个问题. 小数据池和最开始的代码块有什么关系呢?
同样的一段代码在命令行窗⼝和在py文件中. 出现的效果是完全不⼀样的
在代码块内的缓存机制是不一样的. 在执行同一个代码块的初始化对象的命令时, 会检
查是否其值是否已经存在, 如果存在, 会将其重用. 换句话说: 执行同一个代码块时, 遇到初始
化对象的命令时,他会将初始化的这个变量与值存储在一个字典中, 在遇到新的变量时, 会先
在字典中查询记录, 如果有同样的记录那么它会重复使用这个字典中的之前的这个值. 所以在
你给出的例子中, 文件执行时(同一个代码块) 会把a, b两个变量指向同一个对象.
如果是不同的代码块, 他就会看这个两个变量是否是满足小数据池的数据, 如果是满足
小数据池的数据则会指向同一个地址. 所以: a, b的赋值语句分别被当作两个代码块执行, 但
是他们不满足小数据池的数据所以会得到两个不同的对象, 因而is判断返回False.
三、编码的补充
1、python2中默认使用的是ASCII码,所以不支持中文,如果需要在python2中更改编码,数中文
需要在文件开始编写:# -*- encoding:utf-8 -*-
2、python3中使用的是unicode码
编码回顾:
1、ASCII:最早的编码,里面有英文大小写字母,数字,一些特殊字符。没有中文,
8个01代码,8个bit,一个字节
2、GBK:中文国标码,包含了ASCII编码和中文常用编码,16个bit,2个byte
3、unicode:万国码,里面包含了全世界所有国家文字的编码,32个bit,4个byte
4、UTF-8:可变长度的万国码,是unicode的一种实现,最小字符占8位
1、英文:8bit 1byte
2、欧洲文字:16bit 2byte
3、中文:24bit 3byte
综上, 除了ASCII码以外, 其他信息不能直接转换.
在python3的内存中. 在程序运行阶段. 使用的是unicode编码. 因为unicode是万国码. 什么内
容都可以进行显示. 那么在数据传输和存储的时候由于unicode比较浪费空间和资源. 需要把
unicode转存成UTF-8或者GBK进行存储. 怎么转换呢. 在python中可以把文字信息进行编码.
编码之后的内容就可以进行传输了. 编码之后的数据是bytes类型的数据.其实啊. 还是原来的
数据只是经过编码之后表现形式发生了改变而已.
bytes的表现形式:
1. 英文b'alex' 英⽂的表现形式和字符串没什么两样
2. 中文 b'\xe4\xb8\xad' 这是⼀个汉字的UTF-8的bytes表现形式
编码与解码:
编码:encode() 解码:decode
x = "Daniel"
print(x.encode("utf-8")) # b'Daniel'
print(x.encode("gbk")) # b'Daniel'
print(x.encode("ascii")) # b'Daniel'
y = "张家辉"
print(y.encode("utf-8")) # b'\xe5\xbc\xa0\xe5\xae\xb6\xe8\xbe\x89'
print(b'\xe5\xbc\xa0\xe5\xae\xb6\xe8\xbe\x89'.decode("utf-8")) # 张家辉
编码和解码的时候都需要指定编码格式、
国标码转化为utf-8
x = "张家辉"
s = x.encode("gbk") # 得到xd的gbk码
x = s.decode("gbk") # 用gbk解码得到uncode(x)
s1 = x.encode("utf-8") # 在用utf-8将x进行解码