一,id,is,==

  在Python中,id是什么?id是内存地址,那就有人问了,什么是内存地址呢? 你只要创建一个数据(对象)那么都会在内存中开辟一个空间,将这个数据临时加在到内存中,那么这个空间是有一个唯一标识的,就好比是身份证号,标识这个空间的叫做内存地址,也就是这个数据(对象)的id,那么你可以利用id()去获取这个数据的内存地址:

name = '太白'
print(id(name)) # 1585831283968

那么 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.

上面的主要意思是:

Python程序是由代码块构造的。块是一个python程序的文本,他是作为一个单元执行的。

代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块。

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

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

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

  那么,可能有的同学还有一些不理解代码块,可以这样解释:我们都上过学对吧,你们在初中的时候,有没有过值周?就以一个班的学生用一星期的时间打扫整个学校,再比如有没有运动会,无论是值周,还是运动会,还是组织什么活动,都是以什么为单位呢?对,都是以班级为单位,那么咱们学生就好比是代码,班级就好比是代码块,我们想让代码运行起来,必须依靠班级去执行,也就是代码块。

OK,那么现在我们了解了代码块,这和小数据池有什么关系呢?且听下面分析。

代码块的缓存机制

前提条件:在同一个代码块内。

机制内容:Python在执行同一个代码块的初始化对象的命令时,会检查是否其值是否已经存在,如果存在,会将其重用。换句话说:执行同一个代码块时,遇到初始化对象的命令时,他会将初始化的这个变量与值存储在一个字典中,在遇到新的变量时,会先在字典中查询记录,如果有同样的记录那么它会重复使用这个字典中的之前的这个值。所以在你给出的例子中,文件执行时(同一个代码块)会把i1、i2两个变量指向同一个对象,满足缓存机制则他们在内存中只存在一个,即:id相同。

适用对象 int(float),str,bool。

对象的具体细则:(了解)

  int(float):任何数字在同一代码块下都会复用。

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

  str:几乎所有的字符串都会符合缓存机制,具体规定如下(了解即可!):

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

s1 = '太白@!#*ewq'
s2 = '太白@!#*ewq'
print(s1 is s2) # True

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

  2.1 乘数为1时,任何字符串满足代码块的缓存机制:

b1 = '太白@5847395QQ0743895*&^%$#((&_+(())' *1
a1 = '太白@5847395QQ0743895*&^%$#((&_+(())' *1 print(a1 is b1) # True

  2.2 乘数>=2时:仅含大小写字母,数字,下划线,总长度<=20,满足代码块的缓存机制:

s1 = 'old_' * 5
s2 = 'old_' * 5
print(s1 is s2) # True

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

三,小数据池

小数据池,不同代码块的缓存机制,也称为小整数缓存机制,或者称为驻留机制等等,博主认为,只要你在网上查到的这些名字其实说的都是一个意思,叫什么因人而异。

那么到底什么是小数据池?他有什么作用呢?

前提条件在不同一个代码块内。

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

对于整数,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. –引自维基百科

来,我给你们翻译并汇总一下,这个表达的意思就是:

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

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

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

适用对象 int(float),str,bool 

对象的具体细则:(了解即可)

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

那么对于字符串的规定呢?

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

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

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

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

  3.1 乘数为1时:

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

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

含其他字符,长度>1,默认驻留。

  3.2 乘数>=2时:

仅含大小写字母,数字,下划线,总长度<=20,默认驻留。

4,指定驻留。

from sys import intern
a = intern('hello!@'*20)
b = intern('hello!@'*20)
print(a is b)
#指定驻留是你可以指定任意的字符串加入到小数据池中,让其只在内存中创建一个对象,多个变量都是指向这一个字符串。

满足以上字符串的规则时,就符合小数据池的概念。

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

看一下用了小数据池(驻留机制)的效率有多高:

显而易见,节省大量内存在字符串比较时,非驻留比较效率o(n),驻留时比较效率o(1)。

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

四,小结。

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

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

# pycharm 通过运行文件的方式执行下列代码:  这是在同一个文件下也就是同一代码块下,采用同一代码块下的缓存机制。
i1 = 1000
i2 = 1000
print(i1 is i2) # 结果为True 因为代码块下的缓存机制适用于所有数字
通过交互方式中执行下面代码:   # 这是不同代码块下,则采用小数据池的驻留机制。
>>> i1 = 1000
>>> i2 = 1000
>>> print(i1 is i2)
False # 不同代码块下的小数据池驻留机制 数字的范围只是-5~256.

更多验证:

# 虽然在同一个文件中,但是函数本身就是代码块,所以这是在两个不同的代码块下,不满足小数据池(驻存机制),则指向两个不同的地址。
def func():
i1 = 1000
print(id(i1)) # def func2():

i1 = 1000

print(id(i1)) #



func()

func2()

本文大量引用和参考链接如下:

https://zhidao.baidu.com/question/494120409773699052.html

http://mini.eastday.com/bdmip/180405084648167.html

------
转载自:
https://www.cnblogs.com/jin-xin/articles/9439483.html

Python小数据池的更多相关文章

  1. Python小数据池,代码块

    今日内容一些小的干货 一. id is == 二. 代码块 三. 小数据池 四. 总结 python小数据池,代码块的最详细.深入剖析   一. id is == 二. 代码块 三. 小数据池 四. ...

  2. 小学生都能学会的python(小数据池)

    小学生都能学会的python(小数据池) 1. 小数据池. 目的:缓存我们字符串,整数,布尔值.在使用的时候不需要创建过多的对象 缓存:int, str, bool. int: 缓存范围 -5~256 ...

  3. python 小数据池,代码块, is == 深入剖析

    python小数据池,代码块的最详细.深入剖析   一. id is == 二. 代码块 三. 小数据池 四. 总结 一,id,is,== 在Python中,id是什么?id是内存地址,那就有人问了, ...

  4. python -- 小数据池 is和 == 再谈编码

    1.小数据池 python程序是由代码块构成的,一个代码块的文本作为python程序的执行单元. 代码块:一个模块,一个函数,一个类,甚至一个command命令都是一个代码块,一个文件也是一个代码块, ...

  5. python 小数据池,is and "==",decode ,encode

    一:小数据池 1.python运行中的缓存: 2.目的:缓存我们字符串,整数,布尔值.在使用的时候不需要创建过多的对象 3.python 缓存数据:缓存:int, str, bool.         ...

  6. python小数据池,代码块知识

    一.什么是代码块? 根据官网提示我们可以获知: A Python program is constructed from code blocks. A block is a piece of Pyth ...

  7. python小数据池概念以及具体范围

    =   赋值符号:        ==  比较值是否相等:   is  比较,比较的是内存地址      ID(内容) 数字,字符串的小数据池 小数据池现象产生的原因,作用: 为了节省内存空间. &l ...

  8. python小数据池,代码块的最详细、深入剖析

    代码块: Python程序是由代码块构造的.块是 一个python程序的文本,他是作为一个单元执行的. 代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块. 而作为交互方式输入的每个命令都是 ...

  9. python小数据池,代码块深入剖析

    小数据池 目的:缓存我们字符串,整数,布尔值.在使用的时候不需要创建更多的对象 缓存:int,str,bool int:缓存范围-5~256 str:    1.长度小于等于1,直接缓存 2.长度大于 ...

  10. 五.python小数据池,代码块的最详细、深入剖析

    一,id,is,== 在Python中,id是什么?id是内存地址,那就有人问了,什么是内存地址呢? 你只要创建一个数据(对象)那么都会在内存中开辟一个空间,将这个数据临时加在到内存中,那么这个空间是 ...

随机推荐

  1. hello程序的运行过程-从计算机系统角度

    hello程序的运行过程-从计算机系统角度 1.gcc编译器驱动程序读取源程序文件hello.c,并将它翻译成一个可执行目标文件hello.翻译过程分为四个阶段:预处理阶段,编译阶段,汇编阶段,链接阶 ...

  2. PL/SQL 找到某列都为空的列名

    DECLARE CURSOR temp IS SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE TABLE_NAME=Upper('xxx'); v_num ...

  3. js封装ajax

    //封装ajax function ajax(obj) { //创建xhr对象; var xhr = new XMLHttpRequest(); obj.method = obj.method.toU ...

  4. Django(十)模型:django模型类对数据库的:增/删/改/查、自关联、管理器、元选项(指定表名)

    一.插入.更新和删除 调用一个模型类对象的save方法的时候就可以实现对模型类对应数据表的插入和更新. 调用一个模型类对象的delete方法的时候就可以实现对模型类对应数据表数据的删除. 二.自关联 ...

  5. use matplotlib to draw scatter plot

    There are many pionts in this kind of table. How to do it? We can use scatter() to draw it. Code: im ...

  6. P1042 字符统计

    P1042 字符统计 转跳点:

  7. mapper语句的一些问题,union连表查询和mapper中根据条件不同采用不同语句的查询问题

    根据业务要求,不同表查出来的内容天需要一起展示出来,并且还有分页之类的,不同表查询字段也不完全相同,这样就有一个问题,不同表如何接合在一起,不同字段怎么办? 这个问题就需要用到union联合查询,并将 ...

  8. 洛谷 P2426 删数

    题目传送门 解题思路: 区间DP,f[i][j]表示区间i~j可获得的最大值,因为本题的所有区间是可以直接一次性把自己全删掉的,所以所有区间初始化为被一次性删除的值,然后枚举断点,跑区间DP. AC代 ...

  9. Redis 详解 (五) redis的五大数据类型实现原理

    目录 1.对象的类型与编码 ①.type属性 ②.encoding 属性和 *prt 指针 2.字符串对象 3.列表对象 4.哈希对象 5.集合对象 6.有序集合对象 7.五大数据类型的应用场景 8. ...

  10. 148-PHP strip_tags函数,剥去字符串中的 HTML 标签(二)

    <?php //定义一段包含PHP代码的字符串 $php=<<<PHP 这里是PHP代码的开始 <?php echo "hello!"; PHP; $ ...