a = [1,2,3,4,5]
b = a[1]
print id(a[1],b) # out put shows same id.hence both represent same object.
del a[1] # deleting a[1],both a[1],b have same id,hence both are aliases
print a # output: [1,3,4,5]
print b # output: 2
b,a [1]具有相同的id,但删除一个不会影响另一个.Python引用声明'del' on a subscription deletes the actual object,not the name object binding
。输出:[1,3,4,5]证明了这一说法。但是当a[0]
和b
具有相同的id时,“b”如何保持不受影响。
编辑:部分'del' on a subscription deletes the actual object,not the name object binding
不正确。反之亦然。 'del'实际上删除了名称,对象绑定。如果订阅上的'del'(例如del a [1])从列表对象中删除对象2,并删除当前a[1]
绑定到{{1然后让2
绑定到a[1]
。后续索引遵循该模式。
答案 0 :(得分:7)
del
不删除对象,会删除引用。
有一个对象是整数值2
。两个地方提到了一个单一的物体; a[1]
和b
。
您删除了a[1]
,因此该引用已消失。但这对对象 2
没有任何影响,仅对a[1]
中的引用有影响。因此,通过名称b
可访问的引用仍然可以很好地到达对象2
。
即使您del
所有引用都对对象没有影响。 Python是一种垃圾收集语言,因此它负责注意何时对象不再被引用,以便它可以回收对象占用的内存。这将在对象不再可达后的某个时间发生。 1
1 CPython使用引用计数来实现它的垃圾收集 2 ,它允许我们说对象通常会在它们的最后一个引用死亡后立即被回收,但那是实现细节不是语言规范的一部分。您不必完全了解Python如何收集垃圾,也不应该编写依赖它的程序;其他Python实现(如Jython,PyPy和IronPython)不会以这种方式实现垃圾收集。
2 加上一个额外的垃圾收集机制来检测循环垃圾,它引用计数无法处理。
答案 1 :(得分:6)
del
仅减少该对象的引用计数。所以在b = a[1]
之后,a[1]
处的对象有2个(比方说)引用。删除[1]后,它从list
消失,现在只有1个引用,因为它仍由b
引用。在ref之前没有实际删除。 count为0,然后仅在GC循环中。
答案 2 :(得分:2)
这里有多个问题在起作用。首先,在列表成员上调用del
会从列表中删除该项,这会释放对象的引用计数,但由于变量b
仍然引用它,因此不会解除分配。你永远不能解除你引用的东西。
这里需要注意的第二个问题是,接近于零的整数实际上是合并的,并且永远不会被释放。你应该通常不必理解这一点。
答案 3 :(得分:0)
它们具有相同的id
,因为Python会将id
重用于小整数,即使您删除了这些... the docs中提到了这一点:
当前实现为-5到256之间的所有整数保留一个整数对象数组,当您在该范围内创建一个int时,实际上只返回对现有对象的引用。
我们可以看到这种行为:
>>> c = 256
>>> id(c)
140700180101352
>>> del c
>>> d = 256
>>> id(d)
140700180101352 # same as id(c) was
>>> e = 257
>>> id(e)
140700180460152
>>> del e
>>> f = 257
>>> id(f)
140700180460128 # different to id(e) !