详解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编码总结(编码类型、格式、转码)
Jul 01 Python
Python程序中设置HTTP代理
Nov 06 Python
Python爬虫利用cookie实现模拟登陆实例详解
Jan 12 Python
PyQt5每天必学之组合框
Apr 20 Python
python批量修改图片后缀的方法(png到jpg)
Oct 25 Python
python微信聊天机器人改进版(定时或触发抓取天气预报、励志语录等,向好友推送)
Apr 25 Python
Django如何使用第三方服务发送电子邮件
Aug 14 Python
Pandas数据离散化原理及实例解析
Nov 16 Python
Python原始套接字编程实例解析
Jan 29 Python
使用py-spy解决scrapy卡死的问题方法
Sep 29 Python
Pandas对每个分组应用apply函数的实现
Dec 13 Python
pandas 数据类型转换的实现
Dec 29 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
php中static静态变量的使用方法详解
2010/06/04 PHP
Php中用PDO查询Mysql来避免SQL注入风险的方法
2013/04/25 PHP
基于AppServ,XAMPP,WAMP配置php.ini去掉警告信息(NOTICE)的方法详解
2013/05/07 PHP
PHP多线程编程之管道通信实例分析
2015/03/07 PHP
学习YUI.Ext 第二天
2007/03/10 Javascript
使用javascript实现ListBox左右全选,单选,多选,全请
2013/11/07 Javascript
Js操作树节点自动折叠展开的几种方法
2014/05/05 Javascript
node.js中的fs.linkSync方法使用说明
2014/12/15 Javascript
js实现可兼容IE、FF、Chrome、Opera及Safari的音乐播放器
2015/02/11 Javascript
javascript 闭包详解
2015/07/02 Javascript
Bootstrap组件系列之福利篇几款好用的组件(推荐)
2016/06/23 Javascript
jQuery自制提示框tooltip改进版
2016/08/01 Javascript
js自调用匿名函数的三种写法(推荐)
2016/08/19 Javascript
node.js版本管理工具n无效的原理和解决方法
2016/11/24 Javascript
利用JavaScript对中文(汉字)进行排序实例详解
2017/06/18 Javascript
深入理解Vue nextTick 机制
2018/04/28 Javascript
vue 指令之气泡提示效果的实现代码
2018/10/18 Javascript
angular4应用中输入的最小值和最大值的方法
2019/05/17 Javascript
在vue项目中 实现定义全局变量 全局函数操作
2020/10/26 Javascript
python机器学习之神经网络(一)
2017/12/20 Python
Python使用装饰器模拟用户登陆验证功能示例
2018/08/24 Python
python将txt文件读入为np.array的方法
2018/10/30 Python
python切片的步进、添加、连接简单操作示例
2019/07/11 Python
python获取依赖包和安装依赖包教程
2020/02/13 Python
python求前n个阶乘的和实例
2020/04/02 Python
将pymysql获取到的数据类型是tuple转化为pandas方式
2020/05/15 Python
Pandas缺失值2种处理方式代码实例
2020/06/13 Python
python实现发送邮件
2021/03/02 Python
阳光体育:Sunny Sports(购买露营和远足设备)
2018/08/07 全球购物
维多利亚的秘密阿联酋官网:Victoria’s Secret阿联酋
2019/12/07 全球购物
医学检验专业个人求职信范文
2013/12/04 职场文书
酒店总经理岗位职责
2014/03/17 职场文书
先进事迹报告会主持词
2014/04/02 职场文书
山东省召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
MySQL安装后默认自带数据库的作用详解
2021/04/27 MySQL
Python破解极验滑动验证码详细步骤
2021/05/21 Python