小数据池与代码块

. id, is  ==
 1 name = "ad"
 2 
 3 print(id(name))    
 4 # 2738647174536
 5 
 6 # is —— 比较两边的内存地址是否相等
 7 # == —— 比较两边的数值是否相等
 8 i1 = 1000
 9 i2 = 1000
10 print(i1 is i2)
11
12 # 如果是在终端内一步一步输入上面的内容,则相当于 i1 与 i2 是两个代码块,结果就是 False 13 # 反之像现在这样在同一个代码块里的话,结果就是 True 14 # 这里所说的代码块可以理解为一个文件就是一个代码块 15 16 # 在终端里一行 ">>>" 代表一个代码块 17 print(i1 == i2) # True 18 19 # 如果内存地址相同,值一定相同,反之则不一定。

 

. 代码块
1. 作为一个单元执行
一个模块,一个函数,一个类都是一个代码块

2. 代码块的缓存机制:
2.1 Python在执行同一个代码块的初始化对象(也就是设置变量)的命令时,会检查是否其值是否已经存在。如果存在,会将其重用。
2.2 也就是说,遇到初始化对象的命令时,会将初始化的这个变量与值存储在一个字典中,
2.3 在遇到新的变量时,会先在字典中查询,如果有同样的记录,那么它会重复使用这个字典中之前的这个值。比如:
 1 i1 = 100
 2 i2 = 100
 3 
 4 print(id(i1))  # 1407285088
 5 print(id(i2))  # 1407285088
 6 
 7 # 注意与上面 i1 = 1000 那个例子比较看结果
 8 # 程序执行时会把 i1、i2 两个变量指向同一个对象
 9 # 如果满足缓存机制则它们在内存中只存在一个,即它们的 id 相同。
10 # 注意这里重点是在同一个代码块下!
11 
12 a = [1, 2, 3]
13 b = [1, 2, 3]
14 print(a is b)   # False
代码块的缓存机制适用范围:

int(float)
str
bool

int(float) —— 任何数字在同一个代码块中都会复用

bool —— True 和 False 在字典中会以1, 0方式存在,并且复用

str —— 几乎所有的字符串都会符合缓存机制

以上内容表明代码块的缓存机制的优点:
a. 节省内存
b. 提升性能
3. 非乘法得到的字符串都满足代码块的缓存机制。
1 s1 = "as12$%#$"
2 s2 = "as12$%#$"
3 
4 print(s1 is s2)    # True
5 
6 注意这里是在同一个代码块里
7 如果在终端内运行的话相当于在不同代码块里,结果就变了

 1 4 乘法得到的字符串分两种情况:
 2 
 3 4.1 乘数为1时,任何字符串满足代码块的缓存机制:
 4 
 5 b1 = '太白@5847395QQ0743895*&^%$#((&_+(())' * 1
 6 a1 = '太白@5847395QQ0743895*&^%$#((&_+(())' * 1
 7 
 8 print(a1 is b1)  # True
 9 
10 4.2 乘数 >= 2时:仅含大小写字母,数字,下划线,总长度 <= 20,满足代码块的缓存机制:
11 
12 s1 = 'old_' * 5
13 s2 = 'old_' * 5
14 print(s1 is s2)  # True
15 
16 优点:
17 能够提高一些字符串,整数处理人物在时间和空间上的性能;
18 需要值相同的字符串,整数的时候,直接从‘字典’中取出复用,避免频繁的创建和销毁,提升效率,节约内存。

 

三,小数据池

1. 小数据池,也称为小整数缓存机制,或者称为驻留机制等等。

大前提:小数据池也是只针对
int(float),str,bool。

2. 注意,小数据池是针对不同代码块之间的缓存机制

3. Python自动将 -5~256 的整数进行了缓存。
当将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象。

4. python会将一定规则的字符串在字符串驻留池中,创建一份
当将这些字符串赋值给变量时,并不会重新创建对象, 而是使用在字符串驻留池中创建好的对象。

5. 其实,无论是缓存还是字符串驻留池,都是python做的一个优
就是将 -5-256 的整数,和一定规则的字符串,放在一个‘池’(容器,或者字典)中
无论程序中那些变量指向这些范围内的整数或者字符串,那么直接在这个‘池’中引用,即在内存中之创建一个。

5.1 优点:
1) 能够提高一些字符串,整数处理人物在时间和空间上的性能;
2) 需要值相同的字符串,整数的时候,直接从‘池’里拿来用,避免频繁的创建和销毁,提升效率,节约内存。

6. int:那么大家都知道对于整数来说,小数据池的范围是 - 5
~256 ,如果多个变量都是指向同一个(在这个范围内的)数字,他们在内存中指向的都是一个内存地址。

str: 字符串要从下面这几个大方向讨论(了解即可!):

1, 字符串的长度为0或者1,默认都采用了驻留机制(小数据池)。

2, 字符串的长度 > 1, 且只含有大小写字母,数字,下划线时,才会默认驻留。


四,小结。

  如果在同一代码块下,则采用同一代码块下的缓存机制。

  如果是不同代码块,则采用小数据池的驻留机制。

编码:
1. 之前讲过 ASCII、Unicode、UTF-8、GBK这四种编码。

2. 不同的编码之间不能互相识别(报错或出现乱码),不能相互转化

3. 国际通用标准:文字通过网络传输,或者硬盘存储等不能使用Unicode编码方式。
(因为Unicode都是使用升级版32位的,太费流量了)

4. 在 python3x 环境下,唯独 str 类型在内存中的编码方式是 Unicode,
所以字符串不能直接进行网络传输及文件的存储
5. bytes —— 数据类型,不是字节,与 str 类型就像是一对孪生兄弟

1 s1 = "alex"
2 s2 = b"alex"
3 
4 print(type(s1))    # <class 'str'>
5 print(type(s2))    # <class 'bytes'>

那么为啥要有 bytes ? —— bytes内部编码非Unicode方式,因此可以进行网络传输和文件的存储
前面提到,str 类型却是 Unicode方式,那为什么不用 bytes 而是用 str?
因为,bytes 中文是16进制。
因此,当需要网络传输数据,文件存储数据时要考虑用 bytes。

英文
str 的表现形式:"alex"
内部编码: Unicode
中文
str 的表现形式: "中文"
内部编码:Unicode
 1 # 由以上信息,str 转化成 bytes 的方法是:
 2 # unicode --> gbk字符串 --> gbk编码方式的bytes
 3 
 4 s = "中国"  # 因为PythOn3x中 str 编码方式就是 Unicode,所以这里等同于 s = u"中国"
 5 a = s.encode("gbk")
 6 
 7 print(s, type(s))     # ('中国', <class 'str'>)
 8 print(a, type(a))     # (b'\xd6\xd0\xb9\xfa', <class 'bytes'>)
 9 
10 s1 = a.decode("gbk")  # 注意这里是 decode
11 print(s1, type(s1))   # ('中国', <class 'str'>)
12 # 在上面 4-11 行的代码中,首先 s = "中国" 是以 Unicode编码方式的 str
13 # 然后 a = s.encode("gbk") 是将 Unicode 编码方式的 str 转化成 以 gbk 编码方式的 bytes
14 # 最后是 s1 = a.decode("gbk") 则将 gbk 编码方式的 bytes 转化成 以 Unicode 编码方式的 str
15
16 # encode 编码 17 # decode 解码 18 19 # unicode --> utf-8 字符串 --> utf-8 编码方式的bytes 20 21 s2 = "语言" 22 b = s2.encode("utf-8") 23 print(b, type(b)) # (b'\xe8\xaf\xad\xe8\xa8\x80', <class 'bytes'>) 24 s3 = b.decode("utf-8") 25 print(s3, type(s3)) # ('语言', <class 'str'>)

前面提到不同的编码之间不能互相识别(报错或出现乱码),不能相互转化。
因此它们要通过 Unicode 编码方式来相互转化。

 

posted @ 2018-12-26 16:35  星满夜空  阅读(211)  评论(0编辑  收藏  举报