python什么时候删除变量?

python什么时候删除变量?,python,memory,garbage-collection,Python,Memory,Garbage Collection,我知道python有一个自动垃圾收集器,因此当没有更多的变量引用时,它应该自动删除变量 我的印象是局部变量(函数内部)不会发生这种情况 def funz(z): x=f(z)#x是一个np.array,包含大量数据 x0=x[0] y=f(z+1)#y是一个np数组,包含大量数据 y0=y[0] #这里还有x和y吗? 返回y0,x0 delx是节省内存的正确方法吗 def funz(z): x=f(z)#x是一个np.array,包含大量数据 x0=x[0] 德尔克斯 y=f(z+1)#y是一

我知道python有一个自动垃圾收集器,因此当没有更多的变量引用时,它应该自动删除变量

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

def funz(z):
x=f(z)#x是一个np.array,包含大量数据
x0=x[0]
y=f(z+1)#y是一个np数组,包含大量数据
y0=y[0]
#这里还有x和y吗?
返回y0,x0
delx
是节省内存的正确方法吗

def funz(z):
x=f(z)#x是一个np.array,包含大量数据
x0=x[0]
德尔克斯
y=f(z+1)#y是一个np数组,包含大量数据
y0=y[0]
德利
返回y0,x0
编辑:我对我的示例进行了编辑,使其更接近我的实际问题。 在我的实际问题中,x和y不是列表,而是包含不同大数组的类

编辑:我可以运行以下代码:

x=f(z)
x0=x[0]
打印(x0)
y=f(z+1)
y0=[0]
打印(y0)

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

变量超出范围后(如示例中所示),如果没有对它的剩余引用,那么内存将被释放

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中手动删除变量


不过,正如在的答案中所说,使用del可以很好地显示意图。

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

  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] 

这将导致异常

这取决于变量的实现和类型。对于像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
将减少该对象上的引用计数,但即使它降至零,也不能保证很快会被垃圾收集

建议你看一个解释和灵感。然后再想想

如果您的“内存不足”,那么您的设计可能存在一个基本问题。很可能您一次加载了太多数据(尝试使用迭代器?),或者您的代码需要更好的结构

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


另一种选择是使用像SQLite这样的数据库,或者可能是一个

保持两个概念分开很重要:名称和值。Python中的变量是指值的名称。名称具有作用域:定义局部变量(通过为名称赋值)时,变量的作用域为当前函数。当函数返回时,变量消失。但这并不意味着价值消失了

值没有作用域:它们一直存在,直到没有更多的名称引用它们。您可以在函数中创建一个值,然后从该函数返回该值,使函数外部的名称引用该值,并且直到将来某个时候对该值的所有引用都消失后,才会回收该值


更多细节(包括图片!)在这里:。

我的印象是局部变量(在函数内部)不会发生这种情况。是什么给你留下这样的印象?当函数结束时,本地名称被清除;它们引用的对象在引用计数下降到0时被删除,就像Python中的其他任何地方一样。我收到一个内存不足错误。我知道我能够运行这些脚本independently@Donbeo:当函数运行脚本时,您如何运行它们?它们是作为单独的进程运行还是作为模块运行?@MartijnPieters python中的“scope”与许多其他语言中的“scope”不同,这一事实可能会让OP感到困惑。例如,循环的
没有定义新的作用域,其变量在最终迭代后仍然有效。是的,我需要所有列表。这个例子并不完全是我的代码中的例子。在我的代码中,f返回一个类,其中该类中的某些元素是大型np.ndarray。如果我可以用del之类的东西手动删除变量,那么我认为我的问题将得到解决。请注意:垃圾收集和引用计数不是一回事,Python同时做这两件事。然而,垃圾收集主要用于清除循环引用,因此不是内存管理的主要形式。引用计数会在引用计数降至零时释放内存,它不会等待GC循环。当然也有一些例外,因为python会缓存整数和短字符串,即使出于性能原因没有对它们的实时引用。