python 对象引用、可变性 和 垃圾回收
文章目录
- 1. 变量是标签
- 2. 元组的相对不可变性
- 3. 默认浅复制
- 4. 函数的参数作为引用时
- 5. del 和 垃圾回收
- 6. 弱引用
- 7. 一些可能的坑!!!
learn from 《流畅的python》
1. 变量是标签
>>> a = [1, 2, 3]
>>> b = a
>>> a.append(4)
>>> b
[1, 2, 3, 4]
- 对象的 id 在生命周期中是不变的
is
运算检查两者的 id 是否一致==
检查两者内容(值)是否一样is
运算符比==
速度快,因为它不能重载,不用寻找并调用特殊方法
2. 元组的相对不可变性
元组的不可变性 其实是指 tuple 数据结构的 物理内容(即保存的引用)不可变,与引用的对象无关
>>> t1 = (1, 2, [30, 40])
>>> t2 = (1, 2, [30, 40])
>>> t1 is t2
False
>>> t1 == t2
True
>>> id(t1[-1])
2633996005896
>>> t1[-1].append(100)
>>> t1
(1, 2, [30, 40, 100])
>>> id(t1[-1])
2633996005896
>>> t1 == t2
False
如果元组内部有 可变对象,那么元组就 不可散列了
3. 默认浅复制
>>> l1 = [3, [55, 44], (7, 8, 9)]
>>> l2 = list(l1) # 创建副本 或者 [:] ,浅复制
>>> l2
[3, [55, 44], (7, 8, 9)]
>>> l1 == l2
True
>>> l1 is l2
False
构造方法或 [:] 做的是浅复制(即复制了最外层
容器,副本中 的元素是源容器中元素的引用)。
如果所有元素都是不可变的,那么这 样没有问题,还能节省内存。
但是,如果有可变的元素,可能就会导致 意想不到的问题。
>>> l1 = [3, [66, 55, 44], (7, 8, 9)]
>>> l2 = list(l1) # 两者共享内部的 list tuple
>>> l1.append(100)
>>> l1[1].remove(55)
>>> print('l1:', l1)
l1: [3, [66, 44], (7, 8, 9), 100]
>>> print('l2:', l2)
l2: [3, [66, 44], (7, 8, 9)]
>>> l2[1] += [33, 22] # list 变更,反映到 l1
>>> l2[2] += (10, 11) # tuple 不可变,+= 生成新的 tuple ,不反映到 l1
>>> print('l1:', l1)
l1: [3, [66, 44, 33, 22], (7, 8, 9), 100]
>>> print('l2:', l2)
l2: [3, [66, 44, 33, 22], (7, 8, 9, 10, 11)]
- copy 模块 的
deepcopy(),copy()
实现 深复制,浅复制
4. 函数的参数作为引用时
- 可变对象 经过函数修改会传递出来(如果不希望修改原来的,可以创建副本)
- 不可变对象 操作后,会生成新的对象
- 不要用 可变对象作为函数默认值,如
def func(a = [])
>>> def func(a=[]):
... a.append(5)
... print(a)
...
>>> func()
[5]
>>> func()
[5, 5]
>>> func()
[5, 5, 5]
修改了 可变的默认值,后续调用都会受到影响
5. del 和 垃圾回收
del 语句删除名称,而不是对象
del 命令可能会导致对象被 当作垃圾 回收,但是 仅当 删除的变量 保存的是 对象的最后一个引用,或者无法得 到对象时
6. 弱引用
正是因为有引用,对象才会在内存中存在。
当对象的引用数量归零后, 垃圾回收程序会把对象销毁。
但是,有时需要引用对象,而不让对象 存在的时间超过所需时间。这经常用在缓存中。
弱引用不会增加对象的引用数量
。
引用的目标对象 称为 所指对象 (referent)。弱引用 不会妨碍 所指对象被当作垃圾回收。
弱引用在缓存应用中很有用,因为我们 不想仅因为 被缓存引用着 而始终 保存缓存对象
7. 一些可能的坑!!!
>>> a = None
>>> b = None
>>> a is b
True
>>> id(a)
140712131987472
>>> id(b)
140712131987472
>>> a = [1,2]
>>> b = [1,2]
>>> a is b
False
>>> a = (1,2) # list , tuple 相同字面量,id 不同
>>> b = (1,2)
>>> a is b
False
>>> a = "haha" # 相同的字面量字符串,id 一样!!
>>> b = "haha"
>>> a is b
True
>>> a = 5
>>> b = 5
>>> a is b
True
>>> a, b = 0 , 0
>>> a is b
True
>>> a = 5
>>> a
5
>>> b
0
>>> a = "ha"
>>> b = "ha"
>>> a is b
True
>>> a = "good" # 但是也无须担心。。
>>> a
'good'
>>> b
'ha'
>>> a = [1,2]
>>> b = a[:]
>>> b
[1, 2]
>>> a is b
False
>>> a = (1,2)
>>> b = a[:] # 不创建新的副本,而list会创建新的副本
>>> b
(1, 2)
>>> a is b
True
>>> b = tuple(a) # 不创建新的副本,而list会创建新的副本
>>> a is b
True
>>> a = [1,2]
>>> b = list(a) # list 创建副本
>>> b
[1, 2]
>>> a is b
False
python 对象引用、可变性 和 垃圾回收相关推荐
- 流畅的python 对象引用 可变性和垃圾回收
对象引用.可变性和垃圾回收 变量不是盒子 人们经常使用"变量是盒子"这样的比喻,但是这有碍于理解面向对象语言中的引用式变量.Python 变量类似于 Java 中的引用式变量,因此 ...
- 记录学习《流畅的python》的一些知识-----对象引用,可变性和垃圾回收
记录我学习<流畅的python>的过程--对象引用,可变性和垃圾回收 2021.9.22 1.变量不是盒子 2.标识.相等性和别名 3.默认做浅复制 4.函数的参数作为引用时 5.del和 ...
- 《Fluent Python》学习笔记:第 8 章 对象引用、可变性和垃圾回收
本文主要是 Fluent Python 第 8 章的学习笔记.这部分主要是介绍了变量.引用.对象.深拷贝.浅拷贝.垃圾回收等.本章虽然枯燥,但是非常有用. <Fluent Python>学 ...
- [流畅的Python][8][对象引用、可变性和垃圾回收]
第8章 对象引用.可变性和垃圾回收 "你不开心,"白骑士用一种忧虑的声调说,"让我给你唱一首歌安 慰你吧--这首歌的曲名叫作 :<黑线鳕的眼睛>." ...
- 流畅的Python读书笔记-第八章-对象引用、可变性和垃圾回收
第8章:对象引用,可变性和垃圾回收 在Python里面变量不是盒子,而是便利贴,类似于Java中的引用变量,因此最好把它们理解为附加在对象上的标注. 因为变量不过是标注,因此无法阻止为对象贴上多个标注 ...
- python基础编程:基于Python对象引用、可变性和垃圾回收详解
下面小编就为大家带来一篇基于Python对象引用.可变性和垃圾回收详解.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 变量不是盒子 在示例所示的交互式控制台中,无法使用 ...
- 第八章《对象引用、可变性和垃圾回收》(下)
对<流畅的python>的读书笔记以及个人理解 9-20 接着上一篇的内容,上一篇的链接:https://blog.csdn.net/scrence/article/details/100 ...
- Fluent_Python_Part4面向对象,08-ob-ref,对象引用、可变性和垃圾回收
第四部分第8章,对象引用.可变性和垃圾回收 1. 创建对象之后才会把变量分配给对象 变量是对象的标注,是对象的别名,是对象的引用,并不是对象存储的地方. 例子1. 证明赋值语句的右边先执行 class ...
- 第8章 对象引用、可变性和垃圾回收
1 #<流畅的Python>读书笔记 2 # 第四部分 面向对象惯用法 3 # 第8章 对象引用.可变性和垃圾回收 4 5 # 8.1 变量不是盒子 6 # Python 变量类似于 Ja ...
- 对象引用、可变性和垃圾回收
对象引用.可变性和垃圾回收 变量不是盒子 变量不是盒子,而是便利贴,python是先创建对象然后再将变量赋值给对象,当创建对象之后,可以通过id查看对象的内存地址. 例如: class Gizmo:d ...
最新文章
- 算法设计与分析 4 估计递归函数复杂度所提及算法
- python内置函数调用前_python之内置函数(一)
- linux 后端存储,配置NFS网络存储作为cinder的后端存储
- redis.mecmcached和mongoDB的区别
- excel表格在保存时出现“隐私问题警告提示”
- java 插桩 工具_一个基于Eclipse的通用Java程序插桩工具.pdf
- 插件 脚本 线程 进程
- CANN AICPU算子耗时分析及优化探索
- Effective Java (7) - 避免终止方法
- 一个农民工学习LINUX内核的艰辛历程/嵌入式的感受
- 【winfrom】事件与委托
- javabean 是什么?
- java 类省_2019 第十届蓝桥杯大赛软件类省赛 Java A组 题解
- 云服务商拿来主义或大限将至,Elastic 表示将变更开源许可协议并进行诉讼
- 苹果iPhone手机升级系统内存空间变小不够如何解决?
- python 读取TXT文件数据(字符或数值)存放在numpy数组中以及训练集测试集的处理(1)(个人笔记)
- 哔哩下载姬v1.3.3 B站视频下载工具
- 严重:init datasource errorcom.mysql.jdbc.exceptions.jdb4.CommunicationsException:Communications link失败
- 2022新版QQ微信域名防红PHP源码+强制跳转打开
- [转]深度剖析闪电网络
热门文章
- Python 内置函数之 open (文件操作)
- 大学计算机应用基础考试题库,大学计算机应用基础考试题库
- php多文件上传存储到表,PHP 实现一种多文件上传的方法
- Deepin 下安装 LAMP
- flask中关于endpoint端点、url_map映射、view_func视图函数,view_functions、及视图函数名是否何以相同的问题?
- golang switch_为什么程序员都不喜欢使用 switch ,而是大量的 if……else if ?
- matlab数值很小出错,求大神帮忙解决一下,用MATLAB求解动力学数据总是出错~ - 计算模拟 - 小木虫 - 学术 科研 互动社区...
- 驱动框架3——初步分析led驱动框架源码
- shell脚本自动备份MySQL数据库
- 深入理解ES6之迭代器与生成器