Python - 我不知道如何在这段代码中使用x

时间:2016-06-17 07:23:02

标签: python garbage-collection

def test(x):
   def add(y):
      return x+y
   def mul(y):
       return x*y
   return "test"

var x会转到GC吗?

1 个答案:

答案 0 :(得分:1)

Python使用引用计数来管理对象,而不是变量。如果您想知道何时从内存中清除x引用的对象,您需要跟踪它有多少引用。 x只是一个这样的参考。

但是,如果没有其他引用到同一个对象(x是唯一的引用),那么是的,该对象将从内存中删除,因为两个{ {1}}和add不会被mul返回。

test被这两个嵌套函数用作闭包,因此x引用的对象将获得两个额外的引用(通过函数对象闭包)。但是由于函数对象在函数结束时被删除(因为它们只是x中的本地符号),所以它们的闭包也是如此,因此最终的结果是不再有{{1引用的对象的引用在test通话结束时,就像电话会议开始时一样。

闭包单元在某种程度上并不重要,因为它们跟踪变量,而不是直接跟踪对象。闭包只是Python的对象(尽管在解释器中有特殊支持来帮助跟踪原始引用),因此它们也需要引用计数。

您可以使用sys.getrefcount() function查看对象的引用数量:

x

引用计数没有改变,因此test()在函数完成后从未导致其他引用。如果您实际返回了嵌套函数,则会发生这种情况:

>>> import sys
>>> def test(x):
...    def add(y):
...       return x+y
...    def mul(y):
...        return x*y
...    return "test"
...
>>> value = 'foo bar'
>>> sys.getrefcount(value)
2
>>> test(value)
'test'
>>> sys.getrefcount(value)
2

这两个函数都引用相同的闭包单元格,而后者又引用test的值,因此当这两个函数对象仍然存在时,引用计数加1。删除这两个函数会清除闭包单元格(该对象的引用数量下降到0),引用计数再次下降。

一旦>>> def test2(x): ... def add(y): ... return x+y ... def mul(y): ... return x*y ... return {'+': add, '*': add} ... >>> test_result = test2(value) >>> test_result {'+': <function add at 0x104e85b90>, '*': <function add at 0x104e85b90>} >>> sys.getrefcount(value) 3 >>> del test_result['+'] >>> sys.getrefcount(value) 3 >>> del test_result['*'] >>> sys.getrefcount(value) 2 字符串的引用计数变为0,它也将被删除。在上面的示例中,它始终为2,因为每当我尝试访问引用计数时,名称x'foo bar'函数都会引用它。