6.小数据池,编码问题
1. 小数据池
id
id() 查看变量的内存地址
通过id()我们可以查看到一个变量表示的值在内存中的地址
小数据池针对的是: int, str, bool
在py文件中几乎所有的字符串都会缓存.
a = 10 b = 30 print(id(a))#1352229376 print(id(b))#1352230016 lst = ["胡辣汤"] print(id(lst))#3070023188872 lst = [] lst.append("胡辣汤") print(id(lst))#3070023188808 lst1 = [1,2,3]# 两个对象 内存地址是不一样的 lst2 = [1,2,3] print(id(lst1))#2114848899464 print(id(lst2))#2114848899272 s1 = "abc" #内存中没有"abc",创建一个新的0.0001 s2 = "abc" #内存以有力"abc" 直接拿"abc" 0.00000001 print(id(s1),id(s2))#2447874555384 2447874555384 # 把字符串的缓存-> 小数据池 -> String iterning -> 常量池 -> 字符串缓存 #什么数据会缓存 #数字,字符串,布尔值 ==>不可变的数据类型 #字符串.如一连串字符串,几乎都会被缓存 s1 = "alex昨天上厕所没关门. 韩红冲进去了. 面筋歌出来了" s2 = "alex昨天上厕所没关门. 韩红冲进去了. 面筋歌出来了" print(id(s1),id(s2))#2431087496432 2431087496432 # 如果在py文件中写的字符串. 几乎都是缓存的 # 在黑窗口里的写的几乎都不会缓存 # 不同的解释器. 缓存的机制也不一样 # 优点: 可以帮我们快速的创建对象.节省内存. # 缺点: 缓存如果过大. 响应速度会比较慢
is和==的区别
is 判断左右两端内容的内存地址是否一致,如果返回True,哪么可以确定这两个变量使用的是同一个对象
== 判断左右两端的值是否相等,是否一致
当两个变量指向同一个对象的时候. is是True, ==也是True
lst1 = [1,2,3] lst2 = [1,2,3] print(id(lst1),id(lst2))#1634021425544 1634021425480 print(lst1==lst2)#Ture print(lst1 is lst2)#False s1 = "我是小钱" s2 = "我是小钱" print(id(s1),id(s2))#1603830872352 1603830872352 print(s1==s2)#True print(s1 is s2)#True
我们可以这样认为. 如果内存地址相同. 那么值一定是相等的. 如果值相等. 则不一定是同一个对象
小数据池
一种数据缓存机制. 也被称为驻留机制. 各大编程语言中都有类似的东西. 在网上 搜索常量池,小数据池指的都是同一个内容. 小数据池只针对: 整数, 字符串, 布尔值. 其他的数据类型不存在驻留留机制.
在python中对-5到256之间的整数会被驻留在内存中. 将一定规则的字符串缓存. 在使用 的时候, 内存中只会创建一个该数据的对象. 保存在小数据池中. 当使用的时候直接从小数据 池中获取对象的内存用. 而不需要创建一个新的数据. 这样会节省更多的内存区域.
优点: 能够提高一些字符串, 整数的处理速度. 省略的创建对象的过程.
缺点: 在'池'中创建或者插入新的内容会花费更多的时间. 对于数字: -5~256是会被加到小数据池中的. 每次使用都是同一个对象. 对于字符串:
- 如果字符串的长度是0或者1, 都会默认进行缓存
- 字符串长度大于1, 但是字符串中只包含字母, 数字, 下划线时才会缓存
- 用乘法的到的字符串.
①. 乘数为1, 仅包含数字, 字母, 下划线时会被缓存. 如果 包含其他字符, 而长度<=1 也会被驻存,
②. 乘数大于1 . 仅包含数字, 字母, 下划 线这个时候会被缓存. 但字符串长度不能大于20
4. 指定驻留. 我们可以通过sys模块中的intern()函数来指定要驻留的内容.
OK. 到目前为止. 我们已经了解了python的小数据池的一些基本情况了. 但是 还有最后一 个问题. 小数据池和最开始的代码块有什么关系呢? 同样的一段代码在命令行窗口和在py文件中. 出现的效果是完全不一样的.
a = 1000 b = 1000 print(a is b) 注意. 在py文件中.得到的结果是True, 但是在command中就不是了.
在代码块内的缓存机制是不一样的. 在执行同一个代码块的初始化对象的命令时, 会检 查是否其值是否已经存在, 如果存在, 会将其重用. 换句话说: 执行同一个代码块时, 遇到初始化对象的命令时,他会将初始化的这个变量与值存储在一个字典中, 在遇到新的变量时, 会先在字典中查询记录, 如果有同样的记录那么它会重复使用这个字典中的之前的这个值. 所以在你给出的例子中, 文件执行时(同一个代码块) 会把a, b两个变量指向同一个对象.
如果是不同的代码块, 他就会看这个两个变量是否是满足小数据池的数据, 如果是满足小数据池的数据则会指向同一个地址. 所以: a, b的赋值语句句分别被当作两个代码块执行, 但是他们不满足小数据池的数据所以会得到两个不同的对象, 因而is判断返回False.
编码的补充
在python3中. 默认的编码是unicode,我们的字符串就是unicode
在python2中. 默认的编码是ASCII. Cpython.c语言的默认编码是ASCII需要在文件开头写
# -*- encoding:utf-8 -*
unicode弊端:在存储和传输的时候. 是很浪费的
在存储和传输的时候不能直接使用unicode. 必须要对字符串进行编码. 编码成bytes类型
编码回顾
1.ASCll:最早的编码,里面有英文大小写,小写字母,数字,一些特殊字符,没有中文
8个01代码,8个bit,1个byte
GBK:中文国编码,里面包含了ASCll码和中文编码16个bit ,2个byte
UNCODE:万国码,里面包含了世界所有国家文字的编码,32个bit,4个byte包含ASCll
UTF-8:可变长度的万国码,是unicode是一种实现,最小字符占8位
1.英文:8bit 1byte
2.欧洲文字:16bit 2byte
3.中文:24bit 3byte
综上,除了ASCll码以外,其他信息不能直接转换
在python3的内存中. 在程序运行阶段. 使用的是unicode编码. 因为unicode是万国码. 什么内容都可以进行显示. 那么在数据传输和存储的时候由于unicode比较浪费空间和资源. 需要把 unicode转存成UTF-8或者GBK进行存储. 怎么转换呢. 在python中可以把⽂字信息进行编码. 编码之后的内容就可以进行传输了了. 编码之后的数据是bytes类型的数据.其实啊. 还是原来的数据只是经过编码之后表现形式发生了改变而已.
bytes: 字节形式的字符串
1. 英文 b'alex' 英⽂文的表现形式和字符串没什么两样
2. 中文 b'\xe4\xb8\xad' 这是一个汉字的UTF-8的bytes表现形式
1. encode(编码格式) 编码
2. decode(编码格式) 解码
bs = b'\xe6\x88\x91\xe4\xbb\x8a\xe5\xa4\xa9\xe9\x9d\x9e\xe5\xb8\xb8\xe7\x9a\x84\xe5\x9b\xb0' # 把这个bytes转化成gbk的bytes s = bs.decode("utf-8") g = s.encode("gbk") print(g)
记住: 英文编码之后的结果和源字符串一致. 中文编码之后的结果根据编码的不同. 编码结果也不同. 我们能看到. 一个中文的UTF-8编码是3个字节. 一个GBK的中文编码是2个字节. 编码之后的类型就是bytes类型. 在网络传输和存储的时候我们python是保存和存储的bytes 类型. 那么在对方接收的时候. 也是接收的bytes类型的数据. 我们可以使用decode()来进行解码操作. 把bytes类型的数据还原回我们熟悉的字符串
一. 上节课内容回顾 1. 字典 {key:value, key:value.....} 成对的保存数据 字典没有索引. 不能切片, 字典的key必须是可哈希的.不可变的 1. 增加: dic[新key] = 值 dic.setdefault(key, value) 新增, 查询 2. 修改: dic[老key] = 值 dic.update(d) 把d更新到dic中 3. 删除; pop(key) popitem() 随机删除 del dic[key] clear() 清空 4. 查询 for k in dic: k dic[k] get(key) 如果key不存在, 返回None dic[key] 如果key不存在, 报错 setdefault(key, value) 根据key查询出value 5. 相关操作 1. keys() 所有的key 2. values() 所有的value 3. items() 所有的key和value for k, v in dic.items(): # 自动解包 k v set集合 内部元素必须可哈希. 不可变 内部元素不重复 add() 添加 frozenset() 冻结集合. 不可变的. 二. 作业 三. 今日主要内容 1. 小数据池, id() 小数据池针对的是: int, str, bool 在py文件中几乎所有的字符串都会缓存. id() 查看变量的内存地址 2. is和==的区别 is 比较的是内存地址 == 比较的是内容 当两个变量指向同一个对象的时候. is是True, ==也是True 3. 再谈编码 回顾: 1. ascii. 有: 数字, 字母, 特殊字符. 8bit 1byte 128 最前面是0 2. gbk. 包含: ascii, 中文(主要), 日文, 韩文, 繁体文字. 16bit, 2byte. 3. unicode. 包含gbk,ascii,big5... 32bit, 4byte 4. utf-8. 可变长度的unicode. 1. 英文: 8bit,1byte 2. 欧洲文字: 16bit 2byte 3. 中文: 24bit 3byte 不同的编码之间不能随意转换. 中国人gbk和德国人utf-8骂 想要沟通必须通过英文(unicode)(媒介) 在python3中. 默认的编码是unicode,我们的字符串就是unicode 在python2中. 默认的编码是ASCII. Cpython.c语言的默认编码是ASCII unicode弊端:在存储和传输的时候. 是很浪费的 在存储和传输的时候不能直接使用unicode. 必须要对字符串进行编码. 编码成bytes类型 bytes: 字节形式的字符串 1. encode(编码格式) 编码 2. decode(编码格式) 解码 bytes是一种另类的字符串表示形式 "哈哈哈" => \xee\xab\x13\xee\xab\x13\xee\xab\x13 预习: 深浅拷贝(难) 基本数据类型的知识点补充(join) 关于字典和列表的删除 周末作业(zip, day5) 质数 数字的长度
作业