端口映射 短视频开发 map遍历 arduino ant bootstrap后台管理模板 git视频教程 css获取最后一个元素 jquery关闭当前窗口 maya曲线建模 random函数用法 python平台 python字符串匹配 python写入文件 java时间 java开发 java基础学习 java将数据写入文件 java语言是什么 bcdautofix 右键菜单背景 怪物猎人ol捏脸数据 linux解压tar js转int su版本转换器 键盘指法练习软件 笔记本测试软件 html5下载 战斗的召唤 华为下拉开关设置 vue路由跳转 mysql导出数据 奥法隐藏外观 送货单管理系统 php验证码 小米主题编辑器 微信超额20万怎么办 谷歌浏览器升级 机械换装 打开mysql
当前位置: 首页 > 学习教程  > python

Python内存分配机制

2021/2/6 22:30:35 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

创建对象(变量、函数、对象等)后,CPython(解释器)会在内存中为其分配地址。Python有一个id()函数,它可以返回对象的“身份”,也就是内存地址。它实际上是一个唯一的整数。 开始 作为一个实例&am…

创建对象(变量、函数、对象等)后,CPython(解释器)会在内存中为其分配地址。Python有一个id()函数,它可以返回对象的“身份”,也就是内存地址。它实际上是一个唯一的整数。
开始
作为一个实例,让我们创建四个变量并为其赋值:

attr1 = 1
attr2 = "abc"
attr3 = (1,2)
attr4 = ['a',1]
#打印他们的id
print('attr1: ', id(attr1))
print('attr2: ', id(attr2))
print('attr3: ', id(attr3))
print('attr4: ', id(attr4))

打印结果如下所示:
attr1:1747938368
attr2:152386423976
attr3:152382712136
attr4:152382633160
每个变量都被分配了一个新的内存地址(以整数形式表示)。第一个假设是,每当我们使用“ =”给变量赋值时,Python都会创建一个新的内存地址来存储变量,这是100%正确的吗?当然不是!

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

attr5 = attr1
attr6 = attr4
print('attr1: ', id(attr1))
print('attr4: ', id(attr4))
print('attr5: ', id(attr5))
print('attr6: ', id(attr6))

Python打印结果:
attr1:1747938368
attr4:819035469000
attr5:1747938368
attr6:819035469000

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

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

print('attr1: ', id(attr1))
attr1 = 2
print('attr1: ', id(attr1))

这将打印:

attr1: 1747938368
attr1: 1747938400

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

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

print'attr6:'id(attr6))
variable6.append('new'print'attr6:'id(attr6))

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

attr6:678181106888
attr6:678181106888

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

def update_attr(attr_to_update):
    print(id(attr_to_update))
update_attr(attr6)
print('attr6: ', id(attr6))

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

attr6 = ['new']
print('attr6: ', attr6)

def update_attr(attr_to_update):
    attr_to_update.append('inside')
update_attr(attr6)
print('attr6: ', attr6)

这将打印:
attr6:[‘new’]
attr6:[‘new’,‘inside’]
它向我们展示了如何在函数中的更新一个可变的变量,你可以看到函数类和函数外的可变变量都具有相同的ID。

# 打印之前的参数6以及id
print('attr6: ', attr6)

def update_attr(attr_to_update):
    print(id(attr_to_update))
    attr_to_update = ['inside']  # 这一步相当于赋值,而不是更改
update_attr(attr6)
print('attr6: ', attr6)

结果:
attr6:[‘new’]
344115201992
attr6:[‘new’]

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

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

attr_nine ="a"
attr_ten ="a"
print'attr9:'id(attr_nine))
print'attr10:'id(attr_ten))

结果:
attr9:792473698064
attr10:792473698064

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

attr_nine = "a" * 21
attr_ten = "a" * 21
print('attr9: ', id(attr_nine))
print('attr10: ', id(attr_ten))

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

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


本文链接: http://www.dtmao.cc/news_show_2000135.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?