详解python的内存分配机制


Posted in Python onMay 10, 2021

开始

作为一个实例,让我们创建四个变量并为其赋值:

variable1 = 1
variable2 = "abc"
variable3 = (1,2)
variable4 = ['a',1]

#打印他们的ids
print('Variable1: ', id(variable1))
print('Variable2: ', id(variable2))
print('Variable3: ', id(variable3))
print('Variable4: ', id(variable4))

打印结果如下所示:

变量1:1747938368
变量2:152386423976
变量3:152382712136
变量4:152382633160

每个变量都被分配了一个新的内存地址(以整数形式表示)。第一个假设是,每当我们使用“ =”给变量赋值时,Python都会创建一个新的内存地址来存储变量。这是100%正确的吗?当然不是!

我将创建两个新变量(5和6)并使用现有变量的值给它们赋值。

variable5 = variable1
variable6 = variable4

print('Variable1: ', id(variable1))
print('Variable4: ', id(variable4))
print('Variable5: ', id(variable5))
print('Variable6: ', id(variable6))

Python打印结果:

变量1:1747938368
变量4:819035469000
变量5:1747938368
变量6:819035469000

你注意到,Python并未为这两个变量创建新的内存地址吗?这次,它只是把两个新变量都指向了现有变量相同的存储位置。

现在让我们为变量1设置一个新值。注意:整数是不可变数据类型。

print('Variable1: ', id(variable1))
variable1 = 2
print('Variable1: ', id(variable1))

这将打印:

Variable1: 1747938368
Variable1: 1747938400

这意味着每当我们使用=并将新值给现有变量赋值时,就会在内部创建一个新的内存地址来存储该变量。让我们看看它是否成立!

当值是可变数据类型时会发生什么?variable6是一个列表,让我们在列表结尾append一个值并打印其内存地址:

print('Variable6:',id(variable6))
variable6.append('new')
print('Variable6:',id(variable6))

请注意,变量的内存地址保持不变,因为它是可变数据类型,我们仅更新了其元素。

Variable6:678181106888
Variable6:678181106888

让我们创建一个函数并将一个变量传递给它。如果我们在函数内部设置变量的值,它会发生什么?让我们评估一下。

def update_variable(variable_to_update):
    print(id(variable_to_update))
update_variable(variable6)
print('Variable6: ', id(variable6))

请注意,variable_to_update的ID指向变量6的ID。

这意味着如果我们在函数中更新variable_to_update且variable_to_update是可变数据类型,那么variable6的值将更新。我们看一个具体例子:

variable6 = ['new']
print('Variable6: ', variable6)

def update_variable(variable_to_update):
    variable_to_update.append('inside')
update_variable(variable6)
print('Variable6: ', variable6)

这将打印:

Variable6:['new']
Variable6:['new','inside']

它向我们展示了如何在函数中的更新一个可变的变量,你可以看到函数类和函数外的可变变量都具有相同的ID。

如果我们在函数内给变量赋一个新值(而不是更新),无论它是不可变的还是可变的数据类型,那么一旦退出函数,更改将丢失:

print('Variable6: ', variable6)

def update_variable(variable_to_update):
    print(id(variable_to_update))
    variable_to_update = ['inside']
update_variable(variable6)
print('Variable6: ', variable6)

Variable6:['new']
344115201992
Variable6:['new']

现在是一个有趣的场景:Python并不总是为所有新变量创建一个新的内存地址。

最后,如果我们为两个不同的变量分配一个字符串值,例如“ a”,该怎么办?它会创建两个内存地址吗?

variable_nine ="a"
variable_ten ="a"
print('Variable9:',id(variable_nine))
print('Variable10:',id(variable_ten))

注意,这两个变量具有相同的内存位置:

Variable9:792473698064
Variable10:792473698064

如果我们创建两个不同的变量并为其分配一个长字符串值,该怎么办:

variable_nine = "a" * 21
variable_ten = "a" * 21
print('Variable9: ', id(variable_nine))
print('Variable10: ', id(variable_ten))

这次Python为两个变量创建了两个不同内存位置:

Variable9:541949933872
Variable10:541949933944

为什么? 这是因为Python启动时会创建一个内部值缓存,这样做是为了提供更快的结果。Python会为少量整数(如-5到256之间)和较小的字符串值分配了少量的内存地址。这就是我们示例中的短字符串都具有相同ID的原因,而长字符串的ID则不同。

== vs是

有时我们想检查两个对象是否相等。

  • 如果我们使用==,它将检查两个参数是否包含相同的数据
  • 如果我们使用is,那么Python将检查两个对象是否引用相同的对象,此时两个对象的id必须相同
var1 = "a" * 30 
var2 = "a" * 30 
print('var1:',id(var1))#318966315648 
print('var2:',id(var2))#168966317364 

print('==:', var1 == var2)#返回True 
print('is:',var1 is var2)#返回False

以上就是详解python的内存分配机制的详细内容,更多关于python 内存分配机制的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python使用BeautifulSoup分析网页信息的方法
Apr 04 Python
python图像处理之反色实现方法
May 30 Python
python中lambda()的用法
Nov 16 Python
Python把csv数据写入list和字典类型的变量脚本方法
Jun 15 Python
对python opencv 添加文字 cv2.putText 的各参数介绍
Dec 05 Python
解决django 新增加用户信息出现错误的问题
Jul 28 Python
python rsa实现数据加密和解密、签名加密和验签功能
Sep 18 Python
python如何使用socketserver模块实现并发聊天
Dec 14 Python
tensorflow 实现从checkpoint中获取graph信息
Feb 10 Python
matplotlib 生成的图像中无法显示中文字符的解决方法
Jun 10 Python
Python 利用OpenCV给照片换底色的示例代码
Aug 03 Python
python3中celery异步框架简单使用+守护进程方式启动
Jan 20 Python
python-for x in range的用法(注意要点、细节)
May 10 #Python
Django显示可视化图表的实践
python 中[0]*2与0*2的区别说明
May 10 #Python
Python超简单容易上手的画图工具库推荐
python爬虫请求库httpx和parsel解析库的使用测评
May 10 #Python
Python 中数组和数字相乘时的注意事项说明
May 10 #Python
python 实现的截屏工具
You might like
php4的session功能评述(一)
2006/10/09 PHP
用sql命令修改数据表中的一个字段为非空(not null)的语句
2010/06/04 PHP
PHP的switch判断语句的“高级”用法详解
2014/10/01 PHP
php序列化函数serialize() 和 unserialize() 与原生函数对比
2015/05/08 PHP
discuz图片顺序混乱解决方案
2015/07/29 PHP
php 输出json及显示json中的中文汉字详解及实例
2016/11/09 PHP
thinkPHP框架乐观锁和悲观锁实例分析
2019/10/30 PHP
javascript网页关闭时提醒效果脚本
2008/10/22 Javascript
JavaScript可否多线程? 深入理解JavaScript定时机制
2012/05/23 Javascript
JavaScript自动设置IFrame高度的小例子
2013/06/08 Javascript
当达到输入长度时表单自动切换焦点
2014/04/06 Javascript
javascript中with()方法的语法格式及使用
2014/08/04 Javascript
在React框架中实现一些AngularJS中ng指令的例子
2016/03/06 Javascript
Javascript HTML5 Canvas实现的一个画板
2020/04/12 Javascript
JavaScript中${pageContext.request.contextPath}取值问题及解决方案
2016/12/08 Javascript
Bootstrap弹出框modal上层的输入框不能获得焦点问题的解决方法
2016/12/13 Javascript
js实现简单的网页换肤效果
2017/01/18 Javascript
详解AngularJs HTTP响应拦截器实现登陆、权限校验
2017/04/11 Javascript
全面解析Node.js 8 重要功能和修复
2017/06/02 Javascript
Angular.js中下拉框实现渲染html的方法
2017/06/18 Javascript
[01:07:11]Secret vs Newbee 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
python迭代器的使用方法实例
2013/11/21 Python
使用 Python 实现微信公众号粉丝迁移流程
2018/01/03 Python
pandas表连接 索引上的合并方法
2018/06/08 Python
python 进程间数据共享multiProcess.Manger实现解析
2019/09/23 Python
详解Open Folder as PyCharm Project怎么添加的方法
2020/12/29 Python
利用canvas实现图片压缩的示例代码
2018/07/17 HTML / CSS
Roxy美国官网:澳大利亚冲浪、滑雪健身品牌
2016/07/30 全球购物
日本订房网站,预订日本星级酒店/温泉旅馆:Relux(支持中文)
2020/01/03 全球购物
FirstCry阿联酋儿童和婴儿产品网上购物:FirstCry.ae
2021/02/22 全球购物
夜不归宿检讨书
2014/02/25 职场文书
法制宣传教育方案
2014/05/09 职场文书
工厂标语大全
2014/10/06 职场文书
2016春节慰问信范文
2015/03/25 职场文书
工资证明范本
2015/06/12 职场文书
springboot应用服务启动事件的监听实现
2022/04/06 Java/Android