Python 可变类型和不可变类型及引用过程解析


Posted in Python onSeptember 27, 2019

在Python中定义一个数据便在内存中开辟一片空间来存储这个变量的值,这块已经被分配的内存空间便会有一个内存地址。访问这块内存需要用到变量名,变量名实际存储的是变量的地址在内存中的地址,但是使用print()函数得到的确实这块内存中实际的地址。这个就当成规定就好,没必要纠结。

获得变量在内存中的地址,可以使用id()函数。

常规使用

变量之间的赋值其实是把一个变量的内存地址传递给另一个变量,这样两个变量便都指向内存中的同一块空间,因此这两个变量的之是相等的

a = 1
b = a
print("a:%d  b:%d" % (a,b))
print(id(a))
print(id(b))
结果:
a:1  b:1
1711072016

此时如果有第三个变量c的值与a的相等,那么c的地址与a的地址一样。这一点请大家牢记。

a = 1
c = 1
print("a:%d  c:%d" % (a,c))
print(id(a))
print(id(c))
结果:
a:1  c:1
1711072016

此时如果修改变量c的值,那么会在内存中新开辟一块内存来存储这个变量,这块新的内存地址将会赋值给c。

a = 1
c = 1
c = 2
print("a:%d  c:%d" % (a,c))
print(id(a))
print(id(c))
结果:
a:1  c:2
1711072032

基本数据类型作为函数参数

基本数据类型作为函数实参同样是这个道理。

a = 1
print(id(a))
def func(x):
  print(id(x))
  x = 2
  print(id(x))
 
func(a)
结果:
1711072016

列表、字典等高级数据类型的引用

列表字典等高级数据类型的变量名同样存储的变量的实际地址,一个列表名赋值给另一个变量,那么这两个变量便指向内存中的同一块地址。

list1 = [1,2,3]
list2 = list1
print(list1,list2)
print(id(list1),id(list2))
结果:
[1, 2, 3] [1, 2, 3]
57931896

高级数据类型在每集加载进内存的时候内存地址与上一次可能会不同。

此时如果修改list2,也会影响list1的值,但是两个变量在内存中的地址还是不变的。这一点是与基本数据类型不一样的。

list1 = [1,2,3]
list2 = list1
print(list1,list2)
print(id(list1),id(list2))
list2.append(4)
print(list1,list2)
print(id(list1),id(list2))
 
结果:
[1, 2, 3] [1, 2, 3]
43841656
[1, 2, 3, 4] [1, 2, 3, 4]
43841656

此时如果有第三个列表list3的值也是[1,2,3,4],可以推测list3的地址与list1的地址应该是一样的,但是事实并非如此。如果有第三个列表list3的值也是[1,2,3,4],相当于在内存中新开辟一块内存来存储这个值。

list1 = [1,2,3]
list2 = list1
list3 = [1,2,3]
print(list1,list2,list3)
print(id(list1),id(list2),id(list3))
结果:
[1, 2, 3] [1, 2, 3] [1, 2, 3]
16775288 16776768

可变数据类型与不可变数据类型

在python中哪些是可变数据类型,哪些是不可变数据类型。可变数据类型:列表list和字典dict;不可变数据类型:整型int、浮点型float、字符串型string和元组tuple。

用一句话来概括上述过程就是:“python中的不可变数据类型,不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量引用这个对象;可变数据类型,允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python访问纯真IP数据库的代码
May 19 Python
python的构建工具setup.py的方法使用示例
Oct 23 Python
Python实现简单文本字符串处理的方法
Jan 22 Python
python实现守护进程、守护线程、守护非守护并行
May 05 Python
Python面向对象程序设计多继承和多态用法示例
Apr 08 Python
Django中ORM外键和表的关系详解
May 20 Python
如何使用python爬虫爬取要登陆的网站
Jul 12 Python
Django模型修改及数据迁移实现解析
Aug 01 Python
django 自定义过滤器(filter)处理较为复杂的变量方法
Aug 12 Python
Python爬虫爬取电影票房数据及图表展示操作示例
Mar 27 Python
Python参数传递对象的引用原理解析
May 22 Python
浅析python中的del用法
Sep 02 Python
Python操作qml对象过程详解
Sep 26 #Python
python 字典的打印实现
Sep 26 #Python
手把手教你pycharm专业版安装破解教程(linux版)
Sep 26 #Python
QML使用Python的函数过程解析
Sep 26 #Python
python 怎样将dataframe中的字符串日期转化为日期的方法
Sep 26 #Python
python3多线程知识点总结
Sep 26 #Python
详解基于python的多张不同宽高图片拼接成大图
Sep 26 #Python
You might like
漫威DC御用漫画家去世 他的表情包曾走红网络
2020/04/09 欧美动漫
AJAX for PHP简单表数据查询实例
2007/01/02 PHP
建站常用13种PHP开源CMS比较
2009/08/23 PHP
php实现的中秋博饼游戏之掷骰子并输出结果功能详解
2017/11/06 PHP
javascript实现的listview效果
2007/04/28 Javascript
javascript 字符 Escape,encodeURI,encodeURIComponent
2009/07/09 Javascript
javascript结合Canvas 实现简易的圆形时钟
2015/03/11 Javascript
javascript显示中文日期的方法
2015/06/18 Javascript
js的form表单提交url传参数(包含+等特殊字符)的两种解决方法
2016/05/25 Javascript
js基于setTimeout与setInterval实现多线程
2016/06/17 Javascript
BootStrap实现手机端轮播图左右滑动事件
2016/10/13 Javascript
Vue+webpack+Element 兼容问题总结(小结)
2018/08/16 Javascript
AngularJS自定义表单验证功能实例详解
2018/08/24 Javascript
vue项目中仿element-ui弹框效果的实例代码
2019/04/22 Javascript
详解微信小程序胶囊按钮返回|首页自定义导航栏功能
2019/06/14 Javascript
vue实现点击追加选中样式效果
2019/11/01 Javascript
python解析html开发库pyquery使用方法
2014/02/07 Python
python实现稀疏矩阵示例代码
2017/06/09 Python
python脚本作为Windows服务启动代码详解
2018/02/11 Python
tensorflow识别自己手写数字
2018/03/14 Python
解决python中import文件夹下面py文件报错问题
2020/06/01 Python
python实现数字炸弹游戏
2020/07/17 Python
Python request中文乱码问题解决方案
2020/09/17 Python
goodhealth官方海外旗舰店:新西兰国民营养师
2017/12/15 全球购物
马来西亚银饰品牌:JEOEL
2017/12/15 全球购物
请写出char *p与"零值"比较的if语句
2014/09/24 面试题
高中学生期末评语
2014/04/25 职场文书
好人好事演讲稿
2014/09/01 职场文书
2014年个人债务授权委托书范本
2014/09/22 职场文书
面试通知单大全
2015/04/20 职场文书
甲午大海战观后感
2015/06/02 职场文书
企业安全生产规章制度
2015/08/06 职场文书
2015年小学语文教师工作总结
2015/10/23 职场文书
车辆挂靠协议书
2016/03/23 职场文书
alibaba seata服务端具体实现
2022/02/24 Java/Android
Win11 Dev 预览版25174.1000发布 (附更新修复内容汇总)
2022/08/05 数码科技