Python基础之代码块&缓存机制&小数据池

一 id,type,value

之前我们学习过定义变量的三个特征:id,type,value。id代表变量在内存中的位置,type代表变量类型,value代表变量的值。同时,我们知道以下两点:

  • id相同,意味着type和value必定相同
  • value相同,type肯定相同,但是id可能不同

补充:== & is

== 是比较的两边的数值是否相等,而 is 是比较的两边的内存地址是否相等

二 代码块

根据官方文档我们可以了解:

A Python program is constructed from code blocks. A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition. Each command typed interactively is a block. A script file (a file given as standard input to the interpreter or specified as a command line argument to the interpreter) is a code block. A script command (a command specified on the interpreter command line with the ‘-c‘ option) is a code block. The string argument passed to the built-in functions eval() and exec() is a code block.
A code block is executed in an execution frame. A frame contains some administrative information (used for debugging) and determines where and how execution continues after the code block’s execution has completed.
View Code

简单翻译一下:

Python程序是由代码块构造的。块是一个python程序的文本,它是作为一个单元执行的。代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块。

而作为交互方式输入的每个命令都是一个代码块。

什么叫交互方式?就是咱们在cmd中进入Python解释器里面,每一行代码都是一个代码块,例如:

image

而对于一个文件中的两个函数,它们也是两个不同的代码块:

image

三 代码块的缓存机制

上面我们知道了什么是代码块,现在我们来学习代码块的缓存机制。

Python在执行同一个代码块的初始化对象的命令时,会检查其值是否已经存在,如果存在,会将其重用。换句话说:执行同一个代码块时,遇到初始化对象的命令时,他会将初始化的这个变量与值存储在一个字典中,在遇到新的变量时,会先在字典中查询记录,如果有同样的记录那么它会重复使用这个字典中的之前的这个值。下面看一个简单的例子:

image

文件执行时(同一个代码块)会把i1、i3两个变量指向同一个对象(id相同),它们在内存中只存在一个,这就是代码块缓存机制。

代码块的缓存机制的适用范围: int(float),str,bool

  • int(float):任何数字在同一代码块下都会复用
  • bool:True和False在字典中会以1,0方式存在,并且复用
  • str:几乎所有的字符串都会符合缓存机制

str具体规定如下(了解即可!):

1.非乘法得到的字符串都满足代码块的缓存机制:

s1 = "joe1991@#$%"
s2 = "joe1991@#$%"
print(s1 is s2)  # True

2.乘法得到的字符串分两种情况:

  • 乘数为1时,任何字符串满足代码块的缓存机制:
s1 = "joe1991@#$%^&*()" * 1
s2 = "joe1991@#$%^&*()" * 1
print(s1 is s2)  # True
  • 乘数>1时:仅含大小写字母,数字,下划线,总长度<=20,满足代码块的缓存机制:

# 仅含有大小写字母,数字,下划线,总长度<=20
s1 = "joe1991ABC" * 2
s2 = "joe1991ABC" * 2
print(s1 is s2)  # True

# 仅含有大小写字母,数字,下划线,总长度>20
s3 = "joe1991ABC11111111111" * 2
s4 = "joe1991ABC11111111111" * 2
print(s3 is s4)  # False

# 含有特殊字符
s5 = "joe1991@#$%^&*()" * 2
s6 = "joe1991@#$%^&*()" * 2
print(s5 is s6)  # False

代码块的缓存机制的优点:提高性能,节约内存。

四 小数据池

小数据池,也称为小整数缓存机制,或者称为驻留机制等等。到底什么是小数据池?它有什么作用呢?

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

小数据池是针对不同代码块之间的缓存机制!!!

官方对于整数,字符串的小数据池是这么说的:

对于整数,Python官方文档中这么说:
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined.

对于字符串:
Incomputer science, string interning is a method of storing only onecopy of each distinct string value, which must be immutable. Interning strings makes some stringprocessing tasks more time- or space-efficient at the cost of requiring moretime when the string is created or interned. The distinct values are stored ina string intern pool. –引自维基百科
View Code

简单翻译一下:

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

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

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

优点:与同一个代码块中的缓存机制一样,它的优点也是提高性能,节约内存。

4.1 int

image

4.2 str

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

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

image

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

image

3.用乘法得到的字符串,分两种情况

  • 乘数为1时

仅含大小写字母,数字,下划线,默认驻留

image

其他字符,长度<=1,默认驻留

image

含其他字符,长度>1,不驻留

image

  • 乘数>=2时,仅含大小写字母,数字,下划线,总长度<=20,默认驻留

image

4.3 指定驻留

image

指定驻留是指我们可以指定任意的字符串加入到小数据池中,让其在内存中只创建一个对象,多个变量指向同一个字符串

4.4 bool值

bool值就是True,False,无论你创建多少个变量指向True,False,那么他在内存中只存在一个。

五 总结

  • 如果在同一代码块下,则采用同一代码块下的缓存机制
  • 如果是不同代码块,则采用小数据池的驻留机制

 

参考:https://www.cnblogs.com/jin-xin/articles/9439483.html

posted @ 2018-05-28 18:29  Joe1991  阅读(136)  评论(0)    收藏  举报