文章目录

  • 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 对象引用、可变性 和 垃圾回收相关推荐

  1. 流畅的python 对象引用 可变性和垃圾回收

    对象引用.可变性和垃圾回收 变量不是盒子 人们经常使用"变量是盒子"这样的比喻,但是这有碍于理解面向对象语言中的引用式变量.Python 变量类似于 Java 中的引用式变量,因此 ...

  2. 记录学习《流畅的python》的一些知识-----对象引用,可变性和垃圾回收

    记录我学习<流畅的python>的过程--对象引用,可变性和垃圾回收 2021.9.22 1.变量不是盒子 2.标识.相等性和别名 3.默认做浅复制 4.函数的参数作为引用时 5.del和 ...

  3. 《Fluent Python》学习笔记:第 8 章 对象引用、可变性和垃圾回收

    本文主要是 Fluent Python 第 8 章的学习笔记.这部分主要是介绍了变量.引用.对象.深拷贝.浅拷贝.垃圾回收等.本章虽然枯燥,但是非常有用. <Fluent Python>学 ...

  4. [流畅的Python][8][对象引用、可变性和垃圾回收]

    第8章 对象引用.可变性和垃圾回收 "你不开心,"白骑士用一种忧虑的声调说,"让我给你唱一首歌安 慰你吧--这首歌的曲名叫作 :<黑线鳕的眼睛>." ...

  5. 流畅的Python读书笔记-第八章-对象引用、可变性和垃圾回收

    第8章:对象引用,可变性和垃圾回收 在Python里面变量不是盒子,而是便利贴,类似于Java中的引用变量,因此最好把它们理解为附加在对象上的标注. 因为变量不过是标注,因此无法阻止为对象贴上多个标注 ...

  6. python基础编程:基于Python对象引用、可变性和垃圾回收详解

    下面小编就为大家带来一篇基于Python对象引用.可变性和垃圾回收详解.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 变量不是盒子 在示例所示的交互式控制台中,无法使用 ...

  7. 第八章《对象引用、可变性和垃圾回收》(下)

    对<流畅的python>的读书笔记以及个人理解 9-20 接着上一篇的内容,上一篇的链接:https://blog.csdn.net/scrence/article/details/100 ...

  8. Fluent_Python_Part4面向对象,08-ob-ref,对象引用、可变性和垃圾回收

    第四部分第8章,对象引用.可变性和垃圾回收 1. 创建对象之后才会把变量分配给对象 变量是对象的标注,是对象的别名,是对象的引用,并不是对象存储的地方. 例子1. 证明赋值语句的右边先执行 class ...

  9. 第8章 对象引用、可变性和垃圾回收

    1 #<流畅的Python>读书笔记 2 # 第四部分 面向对象惯用法 3 # 第8章 对象引用.可变性和垃圾回收 4 5 # 8.1 变量不是盒子 6 # Python 变量类似于 Ja ...

  10. 对象引用、可变性和垃圾回收

    对象引用.可变性和垃圾回收 变量不是盒子 变量不是盒子,而是便利贴,python是先创建对象然后再将变量赋值给对象,当创建对象之后,可以通过id查看对象的内存地址. 例如: class Gizmo:d ...

最新文章

  1. 算法设计与分析 4 估计递归函数复杂度所提及算法
  2. python内置函数调用前_python之内置函数(一)
  3. linux 后端存储,配置NFS网络存储作为cinder的后端存储
  4. redis.mecmcached和mongoDB的区别
  5. excel表格在保存时出现“隐私问题警告提示”
  6. java 插桩 工具_一个基于Eclipse的通用Java程序插桩工具.pdf
  7. 插件 脚本 线程 进程
  8. CANN AICPU算子耗时分析及优化探索
  9. Effective Java (7) - 避免终止方法
  10. 一个农民工学习LINUX内核的艰辛历程/嵌入式的感受
  11. 【winfrom】事件与委托
  12. javabean 是什么?
  13. java 类省_2019 第十届蓝桥杯大赛软件类省赛 Java A组 题解
  14. 云服务商拿来主义或大限将至,Elastic 表示将变更开源许可协议并进行诉讼
  15. 苹果iPhone手机升级系统内存空间变小不够如何解决?
  16. python 读取TXT文件数据(字符或数值)存放在numpy数组中以及训练集测试集的处理(1)(个人笔记)
  17. 哔哩下载姬v1.3.3 B站视频下载工具
  18. 严重:init datasource errorcom.mysql.jdbc.exceptions.jdb4.CommunicationsException:Communications link失败
  19. 2022新版QQ微信域名防红PHP源码+强制跳转打开
  20. [转]深度剖析闪电网络

热门文章

  1. Python 内置函数之 open (文件操作)
  2. 大学计算机应用基础考试题库,大学计算机应用基础考试题库
  3. php多文件上传存储到表,PHP 实现一种多文件上传的方法
  4. Deepin 下安装 LAMP
  5. flask中关于endpoint端点、url_map映射、view_func视图函数,view_functions、及视图函数名是否何以相同的问题?
  6. golang switch_为什么程序员都不喜欢使用 switch ,而是大量的 if……else if ?
  7. matlab数值很小出错,求大神帮忙解决一下,用MATLAB求解动力学数据总是出错~ - 计算模拟 - 小木虫 - 学术 科研 互动社区...
  8. 驱动框架3——初步分析led驱动框架源码
  9. shell脚本自动备份MySQL数据库
  10. 深入理解ES6之迭代器与生成器