详细分析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基于Tkinter实现的记事本实例
Jun 17 Python
Pycharm技巧之代码跳转该如何回退
Jul 16 Python
python实现生成字符串大小写字母和数字的各种组合
Jan 01 Python
python调用其他文件函数或类的示例
Jul 16 Python
django之状态保持-使用redis存储session的例子
Jul 28 Python
Django1.11配合uni-app发起微信支付的实现
Oct 12 Python
Python描述符descriptor使用原理解析
Mar 21 Python
PyTorch中torch.tensor与torch.Tensor的区别详解
May 18 Python
Python根据指定文件生成XML的方法
Jun 29 Python
浅析Python __name__ 是什么
Jul 07 Python
Python与C/C++的相互调用案例
Mar 04 Python
Django基础CBV装饰器和中间件
Mar 22 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
SONY SRF-M100的电路分析
2021/03/02 无线电
PHP与MYSQL中UTF8编码的中文排序实例
2014/10/21 PHP
PDO防注入原理分析以及注意事项
2015/02/25 PHP
php使用curl打开https网站的方法
2015/06/17 PHP
PHP常见数组函数用法小结
2016/03/21 PHP
TP5(thinkPHP框架)实现后台清除缓存功能示例
2019/05/29 PHP
关于Anemometer图形化显示MySQL慢日志的工具搭建及使用的详细介绍
2020/07/13 PHP
jQuery实现返回顶部功能适合不支持js的浏览器
2014/08/19 Javascript
jQuery插件multiScroll实现全屏鼠标滚动切换页面特效
2015/04/12 Javascript
浅谈JSON.parse()和JSON.stringify()
2015/07/14 Javascript
javascript日期处理函数,性能优化批处理
2015/09/06 Javascript
jQuery实现的简单折叠菜单(折叠面板)效果代码
2015/09/16 Javascript
js实现的万能flv网页播放器代码
2016/04/30 Javascript
JS功能代码集锦
2016/05/04 Javascript
AngularJS使用ng-repeat和ng-if实现数据的删选显示效果示例【适用于表单数据的显示】
2016/12/13 Javascript
从零开始学习Node.js系列教程二:文本提交与显示方法
2017/04/13 Javascript
DataTables添加额外的查询参数和删除columns等无用参数实例
2017/07/04 Javascript
监听angularJs列表数据是否渲染完毕的方法示例
2018/11/07 Javascript
详解如何更好的使用module vuex
2019/03/27 Javascript
vue2.0 解决抽取公用js的问题
2020/07/31 Javascript
利用Python进行异常值分析实例代码
2017/12/07 Python
Centos 升级到python3后pip 无法使用的解决方法
2018/06/12 Python
numpy中loadtxt 的用法详解
2018/08/03 Python
python实现多人聊天室
2020/03/31 Python
python面向对象入门教程之从代码复用开始(一)
2018/12/11 Python
python 发送和接收ActiveMQ消息的实例
2019/01/30 Python
详解利用Python scipy.signal.filtfilt() 实现信号滤波
2019/06/05 Python
python实现二分类的卡方分箱示例
2019/11/22 Python
Python3标准库glob文件名模式匹配的问题
2020/03/13 Python
香港家用健身器材、运动器材及健康美容仪器专门店:FitBoxx
2019/12/05 全球购物
展会邀请函范文
2014/01/26 职场文书
12月红领巾广播稿
2014/02/13 职场文书
2016年“12.3”国际残疾人日活动总结
2016/04/01 职场文书
2019森林防火宣传标语大全!
2019/07/03 职场文书
Python爬取科目四考试题库的方法实现
2021/03/30 Python
Django Paginator分页器的使用示例
2021/06/23 Python