详解python的变量缓存机制


Posted in Python onJanuary 24, 2021

变量的缓存机制

变量的缓存机制(以下内容仅对python3.6.x版本负责)

机制

只要有两个值相同,就只开辟一个空间

为什么要有这样的机制

在计算机的硬件当中,内存是最重要的配置之一,直接关系到程序的运行速度和流畅度。在过去计算机内存资源昂贵而小的年代中,程序的内存管理成为编程中的重要技术之一。python没有C/C++中的指针那样的定义可以编程者自主的控制内存的分配,而是有一套自动的内存地址分配和缓存机制。在这个机制当中,可以把一些相同值的变量在内存中指向同一块区域,而不再重新开辟一个空间,这样就达到了节省内存的目的。

详解python的变量缓存机制
详解python的变量缓存机制

python中使用id()函数查看数据的内存地址

number部分

整型

对于整型而言,-5~~正无穷的范围内的相同值的id地址一致

# 在后续的版本中所有的数的id地址都一致

# 相同
print(id(9999999), id(9999999))
print(id(100), id(100))
print(id(-5), id(-5))

# 不同
print(id(-6), id(-6))

浮点型

对于浮点型而言,非负数范围内的相同值id一致

# 相同
print(id(9999999.0), id(9999999.0))
print(id(100.0), id(100.0))

# 不同
print(id(-5.0), id(-5.0))
print(id(-6.0), id(-6.0))

布尔值

对于布尔值而言,值相同测情况下,id一致

# 相同
print(id(True), id(True))
print(id(False), id(False))

复数

复数在(实数+虚数)这样的结构当中永不相同,只有单个虚数相同才会一致

# 相同
print(id(1j), id(1j))
print(id(0j), id(0j))

# 不同
print(id(1234j), id(3456j))
print(id(1+1j), id(1+1j))
print(id(2+0j), id(2+0j))

容器部分

字符串

字符串在相同的情况下,地址相同

# 相同
print(id('hello '), id("hello "))

# 不同
print(id('msr'), id('wxd'))

字符串配合使*号使用有特殊的情况:

乘数为1:只要数据相同,地址就是相同的

# 等于1,和正常的情况下是一样的,只要值相同地址就是一样的
a = 'hello ' * 1
b = 'hello ' * 1
print(a is b)
a = '祖国' * 1
b = '祖国' * 1
print(a is b)

乘数大于1:只有仅包含数字、字母、下划线时地址是相同的,而且字符串的长度不能大于20

# 纯数字字母下划线,且长度不大于20
a = '_70th' * 3
b = '_70th' * 3
c = '_70th_70th_70th'
print(a, id(a), len(a))
print(b, id(b), len(b))
print(c, id(c), len(c))
print(a is b is c)
'''
结果:
_70th_70th_70th 1734096389168 15
_70th_70th_70th 1734096389168 15
_70th_70th_70th 1734096389168 15
True
'''
# 纯数字字母下划线,长度大于20
a = 'motherland_70th' * 3
b = 'motherland_70th' * 3
c = 'motherland_70thmotherland_70thmotherland_70th'
print(a, id(a), len(a))
print(b, id(b), len(b))
print(c, id(c), len(c))
print(a is b is c)
'''
结果:
motherland_70thmotherland_70thmotherland_70th 2281801354864 45
motherland_70thmotherland_70thmotherland_70th 2281801354960 45
motherland_70thmotherland_70thmotherland_70th 2281801354768 45
False
'''
# 有其它字符,且长度不大于20
a = '你好' * 3
b = '你好' * 3
c = '你好你好你好'
print(a, id(a), len(a))
print(b, id(b), len(b))
print(c, id(c), len(c))
print(a is b is c)
'''
结果:
你好你好你好 3115902573360 6
你好你好你好 3115902573448 6
你好你好你好 3115900671904 6
False
'''

字符串指定驻留

使用sys模块中的intern函数,让变量指向同一个地址,只要字符串的值是相同的,无论字符的类型、长度、变量的数量,都指向同一个内存地址。

语法:intern(string)

from sys import intern

a = intern('祖国70华诞: my 70th birthday of the motherland' * 1000)
b = intern('祖国70华诞: my 70th birthday of the motherland' * 1000)
c = intern('祖国70华诞: my 70th birthday of the motherland' * 1000)
d = intern('祖国70华诞: my 70th birthday of the motherland' * 1000)
e = intern('祖国70华诞: my 70th birthday of the motherland' * 1000)

print(a is b is c is d is e)

元组

元组只有为空的情况下,地址相同

# 相同
print(id(()), id(tuple()))

# 不同
print(id((1, 2)), id((1, 2)))

列表、集合、字典

任何情况下,地址都不会相同

# 列表、非空元组、集合、字典 无论在声明情况下,id表示都不会相同

# 不同
print(id([]), id([]))
print(id(set()), id(set()))
print(id({}), id({}))

总结

# -->Number 部分
1.对于整型而言,-5~正无穷范围内的相同值 id一致
2.对于浮点数而言,非负数范围内的相同值 id一致
3.布尔值而言,值相同情况下,id一致
4.复数在 实数+虚数 这样的结构中永不相同(只有虚数的情况例外,只有虚数的虚数相同才会id一致)

# -->容器类型部分
5.字符串 和 空元组 相同的情况下,地址相同
6.列表,元组,字典,集合无论什么情况 id标识都不同 [空元组例外]

小数据池

以下内容仅对python3.6.8负责

数据在同一个文件(模块)当中,变量存储的的缓存机制就是上述的那样。

但是如果是在不同文件(模块)当中的数据,部分数据就会驻留在小数据池当中。

什么是小数据池

不同的python文件(模块)中的相同数据的本应该是不在同一个内存地址当中的, 而是应该全新的开辟一个新空间,但是这样就造成了内存的空间压力,所以python定义了小数据池的概念,默认允许小部分数据即使在不同的文件当中,只要数据相同就可以使用同一个内存空间,节省内存。

小数据池支持什么类型

小数据池只针对:int、bool、None关键字 ,这些数据类型有效。

int

对于int而言,python在内存中创建了-5 ~ 256 范围的整数,提前驻留在了内存的一块区域,如果是不同文件(模块)的两个变量,声明同一个值,在-5~256这个范围里,那么id一致,两个变量的值都同时指向一个值的地址,节省空间。

# 现在我们打开两个终端,进入python环境中,然后执行下面的指令,你会发现,只有-5 ~ 256范围内的整型的id值相同,而不是之前说过的是-5 ~ 正无穷的范围,这是因为,两个终端环境就相当于两个python文件或者是模块。

print(id(1000))
print(id(500))
print(id(257))
print(id(256))
print(id(-5))
print(id(-6))

详解python的变量缓存机制

其它

布尔、None这些类型都是有效的

# 开启两个终端测试吧
print(id(True))
print(id(False))
print(id(None))

详解python的变量缓存机制

到此这篇关于python的变量缓存机制的文章就介绍到这了,更多相关python的变量缓存机制内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python同时给两个收件人发送邮件的方法
Apr 30 Python
python中偏函数partial用法实例分析
Jul 08 Python
Python用list或dict字段模式读取文件的方法
Jan 10 Python
Python进阶之尾递归的用法实例
Jan 31 Python
Python SQLite3简介
Feb 22 Python
如何在Django中添加没有微秒的 DateTimeField 属性详解
Jan 30 Python
pandas中的ExcelWriter和ExcelFile的实现方法
Apr 24 Python
Python内置函数locals和globals对比
Apr 28 Python
Python 如何展开嵌套的序列
Aug 01 Python
termux中matplotlib无法显示中文问题的解决方法
Jan 11 Python
Django程序的优化技巧
Apr 29 Python
68行Python代码实现带难度升级的贪吃蛇
Jan 18 Python
Python字符串对齐、删除字符串不需要的内容以及格式化打印字符
Jan 23 #Python
利用Python函数实现一个万历表完整示例
Jan 23 #Python
python将YUV420P文件转PNG图片格式的两种方法
Jan 22 #Python
如何使用Python进行PDF图片识别OCR
Jan 22 #Python
详解pandas映射与数据转换
Jan 22 #Python
python实现简单的井字棋游戏(gui界面)
Jan 22 #Python
Django url 路由匹配过程详解
Jan 22 #Python
You might like
php 随机排序广告的实现代码
2011/05/09 PHP
PHP中使用循环实现的金字塔图形
2014/11/08 PHP
源码分析 Laravel 重复执行同一个队列任务的原因
2017/12/25 PHP
Mootools 1.2教程 输入过滤第一部分(数字)
2009/09/15 Javascript
浅谈JavaScript对象的创建方式
2016/06/13 Javascript
Javascript 基础---Ajax入门必看
2016/07/06 Javascript
js前端实现多图图片上传预览的两个方法(推荐)
2016/11/18 Javascript
bootstrap suggest下拉框使用详解
2017/04/10 Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
2017/04/21 jQuery
jQuery实现的点击按钮改变样式功能示例
2018/07/21 jQuery
vue项目部署到Apache服务器中遇到的问题解决
2018/08/24 Javascript
JavaScript日期库date-fn.js使用方法解析
2020/09/09 Javascript
python删除过期文件的方法
2015/05/29 Python
基于python脚本实现软件的注册功能(机器码+注册码机制)
2016/10/09 Python
python批量替换多文件字符串问题详解
2018/04/22 Python
Python 支付整合开发包的实现
2019/01/23 Python
python面试题小结附答案实例代码
2019/04/11 Python
Python 根据数据模板创建shapefile的实现
2019/11/26 Python
Python中的整除和取模实例
2020/06/03 Python
python 如何利用argparse解析命令行参数
2020/09/11 Python
Python reversed反转序列并生成可迭代对象
2020/10/22 Python
Python命令行参数argv和argparse该如何使用
2021/02/08 Python
新西兰领先的内衣店:Bendon Lingerie新西兰
2018/07/11 全球购物
什么是动态端口(Dynamic Ports)?动态端口的范围是多少?
2014/12/12 面试题
Ruby如何创建一个线程
2013/03/10 面试题
室内设计专业学生的自我评价分享
2013/11/27 职场文书
2014的自我评价
2014/01/13 职场文书
护士检查书
2014/01/17 职场文书
小学少先队活动方案
2014/02/18 职场文书
体育运动口号
2014/06/09 职场文书
高一学年自我鉴定范文(3篇)
2014/09/26 职场文书
倡议书作文
2015/01/19 职场文书
吴仁宝观后感
2015/06/09 职场文书
远程教育集中轮训基层干部培训班学习心得体会
2016/01/09 职场文书
2019年教师入党申请书
2019/06/27 职场文书
Oracle配置dblink访问PostgreSQL的操作方法
2022/03/21 PostgreSQL