本站消息

  出租广告位,需要合作请联系站长

  今日名言-想象你自己对困难作出的反应,不是逃避或绕开它们,而是面对它们,同它们打交道,以一种进取的和明智的方式同它们奋斗 。——马克斯威尔·马尔兹

  今日名言-用谅解、宽恕的目光和心理看人、待人。人就会觉得葱笼的世界里,春意盎然,到处充满温暖。——蔡文甫


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

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

发布于2021-07-25 07:47     阅读(1048)     评论(0)     点赞(23)     收藏(0)


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

原文链接:https://blog.csdn.net/qq_21201267/article/details/118957860



所属网站分类: 技术文章 > 博客

作者:听见那声音

链接:http://www.pythonpdf.com/blog/article/535/07a01cb1c0fd30198a9b/

来源:编程知识网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

23 0
收藏该文
已收藏

评论内容:(最多支持255个字符)