详细分析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多进程操作实例
Nov 21 Python
python中list列表的高级函数
May 17 Python
Python 异常处理的实例详解
Sep 11 Python
python类的方法属性与方法属性的动态绑定代码详解
Dec 27 Python
更换Django默认的模板引擎为jinja2的实现方法
May 28 Python
解决Python 中英文混输格式对齐的问题
Jul 16 Python
PyTorch搭建多项式回归模型(三)
May 22 Python
python中sort和sorted排序的实例方法
Aug 26 Python
django实现用户注册实例讲解
Oct 30 Python
python 解决tqdm模块不能单行显示的问题
Feb 19 Python
基于 Python 实践感知器分类算法
Jan 07 Python
使用pandas读取表格数据并进行单行数据拼接的详细教程
Mar 03 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读取二进制流(C语言结构体struct数据文件)的深入解析
2013/06/13 PHP
php检测iis环境是否支持htaccess的方法
2014/02/18 PHP
PHP弱类型的安全问题详细总结
2016/09/25 PHP
PHP面向对象之事务脚本模式(详解)
2017/06/07 PHP
PHP PDOStatement::nextRowset讲解
2019/02/01 PHP
论坛里点击别人帖子下面的回复,回复标题变成“回复 24# 的帖子”
2009/06/14 Javascript
基于jquery用于查询操作的实现代码
2010/05/10 Javascript
基于Jquery的实现回车键Enter切换焦点
2010/09/14 Javascript
拉动滚动条加载数据的jquery代码
2012/05/03 Javascript
window.open()实现post传递参数
2015/03/12 Javascript
JavaScript字符串删除重复字符的方法
2015/12/25 Javascript
基于BootStrap Metronic开发框架经验小结【二】列表分页处理和插件JSTree的使用
2016/05/12 Javascript
jQuery插件实现文件上传功能(支持拖拽)
2020/08/27 Javascript
BootStrap Datetimepicker 汉化的实现代码
2017/02/10 Javascript
JavaScript比较两个数组的内容是否相同(推荐)
2017/05/02 Javascript
浅谈Express异步进化史
2017/09/09 Javascript
ajax请求data遇到的问题分析
2018/01/18 Javascript
JS常见构造模式实例对比分析
2018/08/27 Javascript
微信小程序实现留言功能
2018/10/31 Javascript
JS如何实现动态添加的元素绑定事件
2019/11/12 Javascript
vue实现移动端H5数字键盘组件使用详解
2020/08/25 Javascript
JS sort排序详细使用方法示例解析
2020/09/27 Javascript
精确查找PHP WEBSHELL木马的方法(1)
2011/04/12 Python
Python数据结构与算法之链表定义与用法实例详解【单链表、循环链表】
2017/09/28 Python
Python使用Dijkstra算法实现求解图中最短路径距离问题详解
2018/05/16 Python
python3基于OpenCV实现证件照背景替换
2018/07/18 Python
python绘制BA无标度网络示例代码
2019/11/21 Python
python操作cfg配置文件方式
2019/12/22 Python
Python参数传递及收集机制原理解析
2020/06/05 Python
Ratchet 模态框的实现
2020/08/19 HTML / CSS
linux面试题参考答案(7)
2012/10/29 面试题
语文教育专业应届生求职信
2013/11/23 职场文书
法学专业大学生实习自我鉴定
2014/10/05 职场文书
2014小学数学教研组工作总结
2014/12/06 职场文书
筑梦中国心得体会
2016/01/18 职场文书
redis requires ruby version2.2.2的解决方案
2021/07/15 Redis