详细分析Python可变对象和不可变对象


Posted in Python onJuly 09, 2020

在 Python 中一切都可以看作为对象。每个对象都有各自的 id, type 和 value。

  1. id: 当一个对象被创建后,它的 id 就不会在改变,这里的 id 其实就是对象在内存中的地址,可以使用 id() 去查看对象在内存中地址。
  2. type: 和 id 一样当对象呗创建之后,它的 type 也不能再被改变,type 决定了该对象所能够支持的操作
  3. value: 对象的值

一个对象可变与否就在于 value 值是否支持改变。

不可变对象

常见的不可变对象(immutable objects):

  1. Number: int, float, complex
  2. string
  3. tuple
  4. frozenset:set 的另外一种类型

让我们通过例子感受一下

例子

>>> x=1
>>> y=x
>>> id(x)==id(y)
True
>>> id(1)==id(y)
True

这里创建了两个 int 对象,并且让 x,y 指向同一个对象,然后我们试着修改一下 x,让 x+1

>>>x=x+1

这个时候 x 的 id 值和 y 的 id 以及 1 的 id 还一样吗?

>>> x=x+1
>>> id(x)==id(y)
False
>>> id(x)==id(1)
False
>>> id(1)==id(y)
True

从结果不难看出来,x 所指向的对象已经改变了,但是 1 并没有改变。这就是不可变对象,对于不可变对象来说,一旦创建之后就不允许被改变。

注意: 不可变并不严格等同绝对的不可变

>>> a=([1],2,3)
>>> id(a)
4338862696
>>> id(a[0])
4338949128
>>> a[0][0]=0
>>> id(a)
4338862696
>>> id(a[0])
4338949128

从上面的例子不难看出,我们改变了 a[0] 的值,但是并没有影响它的 id 值。一个不可变容器对象如果包含对可变对象的引用,当后者的值改变时,前者的值也会改变;但是该容器仍属于不可变对象,因为它的 id 值不会改变的。

可变对象

常见的可变对象(mutable objects):

  1. list
  2. dict
  3. set

同样的通过例子感受一下

例子

>>> c = [1,2,3]
>>> b = c
>>> id(b)==id(c)
True

创建两个 list 对象,并且让 c,d 指向同一个对象,然后我们试着修改一下 c

c[0]=4

这个时候在看一下两个对象的 id 值是否一致

>>> id(c)==id(b)
True

修改之后,c,d 仍然指向同一个对象,所以不难得出结论,对于一个可变对象来说,修改 value 值并不会对它的 id 造成任何影响

函数参数

对于可变对象和不可变对象,他们两者在函数当作参数传递的时候表现也有所不同

例子

eg0

def update_list(nums_list):
  print(f'2 id:{id(nums_list)}')
  nums_list += [10]
  print(f'3 id:{id(nums_list)}')

  
number_list = [5, 6]
print(f'1:{number_list}, id:{id(number_list)}')   
update_list(number_list)
print(f'4:{number_list}, id:{id(number_list)}')

看一下结果

1:[5, 6], id:4457707912
2 id:4457707912
3 id:4457707912
4:[5, 6, 10], id:4457707912

在看另外一个例子

eg1

def add_num(number):
  print(f'2:{id(number)}')
  number += 1
  print(f'3:{id(number)}')


num = 1
print(f'1:{num}, id:{id(num)}')   
add_num(num)
print(f'4:{num}, id:{id(num)}')

看一下结果

1:1, id:4343768416
2 id:4343768416
3 id:4343768448
4:1, id:4343768416

有其他有些文章中,上面 eg0 被称为引用传递,eg1 被称为值传递。然而在官方文档中,并没有找到有关的这两个名词的任何内容,或者这种方式并不是上述的两者任意一种。

这里的重点是:对于可变对象,在函数中的值的改变,会导致对象改变;对于不可变对象,在函数中值的改变,对其不会造成任何影响

以上就是详细分析Python可变对象和不可变对象的详细内容,更多关于Python可变对象和不可变对象的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python正则表达式判断字符串是否是全部小写示例
Dec 25 Python
Python中实现两个字典(dict)合并的方法
Sep 23 Python
python版微信跳一跳游戏辅助
Jan 11 Python
python打包压缩、读取指定目录下的指定类型文件
Apr 12 Python
python邮件发送smtplib使用详解
Jun 16 Python
python 从文件夹抽取图片另存的方法
Dec 04 Python
python实现自动获取IP并发送到邮箱
Dec 26 Python
python 实现12bit灰度图像映射到8bit显示的方法
Jul 08 Python
Python @property原理解析和用法实例
Feb 11 Python
Keras使用tensorboard显示训练过程的实例
Feb 15 Python
Django中的JWT身份验证的实现
May 07 Python
Python+tkinter实现高清图片保存
Mar 13 Python
OpenCV4.1.0+VS2017环境配置的方法步骤
Jul 09 #Python
详解Python直接赋值,深拷贝和浅拷贝
Jul 09 #Python
使用python实现下载我们想听的歌曲,速度超快
Jul 09 #Python
Python selenium模块实现定位过程解析
Jul 09 #Python
Python自动化操作实现图例绘制
Jul 09 #Python
解决pip install psycopg2出错问题
Jul 09 #Python
利用python下载scihub成文献为PDF操作
Jul 09 #Python
You might like
解析php中mysql_connect与mysql_pconncet的区别详解
2013/05/15 PHP
三个思路解决laravel上传文件报错:413 Request Entity Too Large问题
2017/11/13 PHP
深入理解Javascript中的循环优化
2013/11/09 Javascript
自己编写的支持Ajax验证的JS表单验证插件
2015/05/15 Javascript
JavaScript原生xmlHttp与jquery的ajax方法json数据格式实例
2015/12/04 Javascript
JavaScript开发Chrome浏览器扩展程序UI的教程
2016/05/16 Javascript
JavaScript中常见的八个陷阱总结
2017/06/28 Javascript
vue中遇到的坑之变化检测问题(数组相关)
2017/10/13 Javascript
基于Nodejs的Tcp封包和解包的理解
2018/09/19 NodeJs
vue路由事件beforeRouteLeave及组件内定时器的清除方法
2018/09/29 Javascript
Vue动态面包屑功能的实现方法
2019/07/01 Javascript
javascript实现函数柯里化与反柯里化过程解析
2019/10/08 Javascript
jquery实现吸顶导航效果
2020/01/08 jQuery
浏览器JavaScript调试功能无法使用解决方案
2020/09/18 Javascript
vue 如何从单页应用改造成多页应用
2020/10/23 Javascript
[03:56]显微镜下的DOTA2第十一期——鬼畜的死亡先知播音员
2014/06/23 DOTA
Python实现LRU算法的2种方法
2015/06/24 Python
Python学习笔记之解析json的方法分析
2017/04/21 Python
Python从单元素字典中获取key和value的实例
2018/12/31 Python
很酷的python表白工具 你喜欢我吗
2019/04/11 Python
python3 property装饰器实现原理与用法示例
2019/05/15 Python
Django使用 Bootstrap 样式修改书籍列表过程解析
2019/08/09 Python
python 中值滤波,椒盐去噪,图片增强实例
2019/12/18 Python
pytorch-神经网络拟合曲线实例
2020/01/15 Python
python爬虫快速响应服务器的做法
2020/11/24 Python
基于Python采集爬取微信公众号历史数据
2020/11/27 Python
Skyscanner澳大利亚:全球领先的旅游搜索网站
2018/03/24 全球购物
下列程序在32位linux或unix中的结果是什么
2015/01/26 面试题
报纸媒体创意广告词
2014/03/17 职场文书
小学教师师德承诺书
2014/05/23 职场文书
公司经营目标责任书
2015/01/29 职场文书
清洁工个人工作总结
2015/03/05 职场文书
中国梦党课学习心得体会
2016/01/05 职场文书
《分数乘法》教学反思
2016/02/24 职场文书
pytorch MSELoss计算平均的实现方法
2021/05/12 Python
SQL Server表分区降低运维和维护成本
2022/04/08 SQL Server