以下是我在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
答案 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
变量保持活动状态。通常,当执行离开函数时,其局部变量将不复存在。