在Python Closure中记住了值,并且范围从内存中消失了

时间:2016-04-22 19:29:08

标签: python closures

以下是我在this教程中找到的一段简单代码。

这里有一个很好的Closure定义我发现here"一个函数对象,它记住封闭范围内的值,无论这些范围是否仍然存在于内存中。&#34 ;

我认为下面rotate()是一个闭包。请帮助我理解它的记忆范围是什么,即使它们的范围从记忆中消失了(为什么它们的范围会留下记忆)?

def make_rotater(seq):
    def rotate():
        val = seq.pop(0)
        seq.append(val)
        return val
    return rotate

r = make_rotater([1,2,3])
r()
# 1
r()
# 2

(更新)第2部分:为什么下面的(无关闭)代码不起作用?

def make_rotater(seq):
    val = seq.pop(0)
    seq.append(val)
    return val

r = make_rotater([1,2,3])
r()
# File "<stdin>", line 1, in <module>
# TypeError: 'int' object is not callable

2 个答案:

答案 0 :(得分:2)

它会记住make_rotator中的本地值,所以如果你这样做:

def make_rotater():
    seq=[1,2,3]
    def rotate():
        val = seq.pop(0)
        seq.append(val)
        return val
    return rotate

seq由rotate引用,因此当你调用rotate时它会保留在内存中,即使它是在make_rotater中定义的(已经完成,并从内存中清除)

当你调用make_rotater时,它会创建一个新的seq并定义引用seq的rotate方法,所以除了seq之外你不需要make_rotater它的内存,(因为rotate仍然使用它)。当您不再引用旋转时,seq也将被清除

第2部分:

你的方法现在不会返回另一个直接返回数字的方法,所以你不需要做r()

你可以像这样使用它:

seq = [1,2,3]
def make_rotater(seq):
    val = seq.pop(0)
    seq.append(val)
    return val

r = make_rotater(seq)

print r # prints 1, note there is no r() just r
r = make_rotater(seq)
print r # prints 2
r = make_rotater(seq)
print r # prints 3

答案 1 :(得分:1)

这个定义是正确的,有点不对。这取决于你所说的范围是什么意思&#34;仍然存在于记忆中&#34;。我说更好的定义是&#34;一个函数对象,它会记住封闭范围中的变量,无论这些范围是否仍然存在于调用堆栈 &#34;

致电make_rotater时:

def make_rotater(seq):
    def rotate():
        val = seq.pop(0)
        seq.append(val)
        return val
    return rotate

即使执行离开rotate的范围,seq闭包也会使make_rotater变量保持活动状态。通常,当执行离开函数时,其局部变量将不复存在。