什么时候python删除变量?

时间:2014-08-13 12:28:29

标签: python memory garbage-collection

我知道python有一个自动垃圾收集器,所以它应该在没有更多引用时自动删除变量。

我的印象是局部变量(函数内部)不会发生这种情况。

def funz(z):
    x = f(z) # x is a np.array and contains a lot of data 
    x0 = x[0]
    y = f(z + 1) # y is a np.array and contains a lot of data
    y0 = y[0]  

    # is x still available here ?
    return y[0], x[0] 

是del x保存内存的正确方法吗?

   def funz(z):
        x = f(z) # x is a np.array and contains a lot of data 
        x0 = x[0]
        del x
        y = f(z + 1) # y is a np.array and contains a lot of data
        y0 = y[0]  

        return y[0], x[0] 
编辑:我编辑了我的例子,这与我的真实问题更相似。 在我的实际问题中,x和y不是列表,而是包含不同长np.array的类

编辑:我能够运行代码:

x = f(z)
x[0]
print(x0)

y = f(z + 1)
y0 = [0]
print( y0)

4 个答案:

答案 0 :(得分:11)

实现使用引用计数来确定何时应删除变量。

如果变量超出范围(如在您的示例中),如果没有剩余的引用,则将释放内存。

def a():
    x = 5 # x is within scope while the function is being executed
    print x

a()
# x is now out of scope, has no references and can now be deleted

除了列表中的字典键和元素之外,通常很少有理由在Python中手动删除变量。

虽然如this question的答案所述,但使用del可能有助于显示意图。

答案 1 :(得分:4)

将两个概念分开是很重要的:名称和值。 Python中的变量是一个引用值的名称。名称具有范围:当您定义局部变量(通过为名称赋值)时,变量的范围是当前函数。当函数返回时,变量消失。但这并不代表价值消失。

值没有范围:它们会一直存在,直到没有更多名称引用它们为止。您可以在函数中创建一个值,并从该函数返回它,在函数外部使用一个名称来引用该值,并且该值不会被回收,直到将来所有对它的所有引用都消失之后的某个点

更多细节(包括图片!)在这里:Facts and Myths about Python Names and Values

答案 2 :(得分:0)

在单独的函数中写入要从内存中清除的内容。在您的示例中,您可以执行

  def xdef(z):
    x = f(z) # x is a np.array and contains a lot of data 
    x0 = x[0]

  def funz(z):
    xdef(z)
    y = f(z + 1) # y is a np.array and contains a lot of data
    y0 = y[0]  

    return y[0], x[0] 

这会导致异常

答案 3 :(得分:0)

这取决于实现和变量的类型。对于像int这样的简单对象,有一些优化。例如,在CPython中,即使在使用del之后,简单的int也将重用相同的内存。你不能指望它,但它确实说明事情比它们看起来更复杂。

请记住,当您del删除名称时,不一定是对象 例如:

# x is a np.array and contains a lot of data

措辞更准确:

# x references a np.array which contains a lot of data

del将减少该对象的引用计数,但即使它降至零,也不能保证很快就会被垃圾回收。

建议您查看the gc module的解释和灵感。然后再想一想。

如果你得到记忆力不足"那么你的设计可能存在根本问题。您很可能一次性加载太多数据(尝试使用迭代器?),或者您的代码可能需要更好地构建。

我刚看到你的编辑。你是否同时需要内存中的所有数组?你能用发电机吗?

另一种方法是使用像SQLite这样的数据库,或者使用shelve