如果仍然引用了某些部分
,python垃圾收集器是否会清除复合对象e.g。
def foo():
A = [ [1, 3, 5, 7], [2, 4, 6, 8]]
return A[1]
B = foo()
A[0]
会被垃圾收集吗?
有没有办法通过代码确认相同的内容?
答案 0 :(得分:14)
没有引用列表A
和嵌套列表A[0]
,所以是的,它们将从内存中删除。
A[1]
引用的嵌套列表对象与其原始容器没有连接。
请注意,这不是垃圾收集器; GC仅涉及打破循环引用。这个简单的案例完全由引用计数处理。
当foo()
返回时,将清除本地命名空间。这意味着A
被删除,这意味着列表对象引用计数降为0.这将清除该列表对象,这意味着包含列表也会看到它们的引用计数减一。对于A[0]
,这意味着计数也会下降到0并且被清除。
对于A[1]
引用的列表对象,您现在有一个引用B
,因此它的计数仍然是1并且它仍然是“活着的”。
要通过代码确认相同内容,只需使用list
的子类__del__
method即可告知我们何时删除该对象:
>>> class DelList(list):
... def __del__(self):
... print 'Deleted {}'.format(self)
...
>>> def foo():
... A = DelList([DelList([1, 3, 5, 7]), DelList([2, 4, 6, 8])])
... return A[1]
...
>>> B = foo()
Deleted [[1, 3, 5, 7], [2, 4, 6, 8]]
Deleted [1, 3, 5, 7]
>>> del B
Deleted [2, 4, 6, 8]
所有这些都是CPython特有的(参考Python实现);其他实现可以不同地处理对象生存期(例如,使用垃圾收集器来销毁扫描中的对象),但A
和A[0]
的生命周期在这些情况下不会改变;尽管可能在不同的时间点,GC仍会收集其他实施中的那些。
答案 1 :(得分:0)
Martijn解释说将会收集A[0]
,以下是如何使用代码进行观察:
class Bye(object):
def __del__(self):
"""A special method, called when the object is destroyed."""
print 'bye'
def foo():
A = [Bye(), [1,2]]
return A[1]
foo()
打印:
bye
[1, 2]