0

我对 get() 函数的工作原理感到困惑。它如何读取以前的值?这些值是否存储在 f 函数中?如何?

def nonlocalist():
    get = lambda x:'Index out of range!'
    def prepend(value):
        nonlocal get
        f = get
        def get(i):
            if i == 0:
                return value
            return f(i - 1)
    return prepend, lambda x: get(x)

prepend, get = nonlocalist()
prepend(2)
prepend(3)
prepend(4)

get(2)
4

1 回答 1

0

这些值存储在函数对象中。每次调用prepend都会创建一个新get的函数对象,该对象引用前面的get函数对象,该函数对象仍然存在,并且创建的每个get函数对象都prepend存储value传递给 的参数prepend

nonlocalist被调用时,get指的是返回“索引超出范围!”的 lambda 函数 信息。让我们称之为get0. (这个术语只是为了这个讨论而定义的。它在代码本身中没有任何意义。)

然后 whenprepend在那之后被调用,它设置f为引用get0。然后它重新定义get并且新的get函数对象将value传递给prepend绑定到其中。我们将调用这个新get函数get1。现在如果get1用零参数调用,它将返回传递给的值prepend。如果使用任何其他参数调用它,它将调用f,它指的是get0,参数为零,并且正如我们所见,该函数将返回错误消息,而不管其参数如何。

此时,该get1函数存在,因为它刚刚被定义,并且该get0函数仍然存在,因为get1它持有对它的引用f

下一次调用prepend生成一个新的函数对象get2,该对象存储该prepend调用value和调用get1(as f)。当它调用 时f,它会从下标参数中减去 1 i,从而i控制f调用在列表中向下传播的距离。

所以每次调用都会prepend生成一个新的不同的getn函数对象,其中包含一个valuefromprepend和一个对前面get(n - 1)函数的引用,一直返回到get0.

总之,我必须说:这是一个粗糙的函数巢。

于 2020-06-30T08:11:03.417 回答