如何在嵌套函数中为以后捕获值?

How to capture a value for later in a nested function?

def make_functions():
    flist = []

    for i in [1, 2, 3]:
        def print_i():
            print(i)
        flist.append(print_i)

    return flist

functions = make_functions()
for f in functions:
    f()

这段代码的输出是:

3
3
3

问题:

  1. 为什么print_i只捕获i的最终值?
  2. 我们如何修改这段代码使其打印 1, 2, 3

回答问题 #2 的一种方法如下,但我想知道是否有更优雅的方法来捕获 i.

的值
def make_functions():
    flist = []

    for i in [1, 2, 3]:
        def print_i(j):
            print(j)
        flist.append((print_i, i))

    return flist

functions = make_functions()
for f, i in functions:
    f(i)

因为i的范围在你的情况下是make_functions,你应该为它做一个单独的范围,这里我把它包装成一个函数

def make_functions():
    flist = []

    for i in [1, 2, 3]:
        def print_i_factory(i):
            def print_i():
                print(i)

            return print_i

        flist.append(print_i_factory(i))

    return flist

functions = make_functions()
for f in functions:
    f()

  1. 就像上面的用户说的,你的i的范围是make_function。因此,当执行函数时,它们会在该范围内打印 i 的值 3。这是因为函数与主体 print(i) 一起保存,而没有任何概念 i 位于那一刻。 i 直到稍后调用函数时才会计算,此时 i 已经是 3.

  2. 要回答问题2,我们需要在print_i函数的范围内得到i。我们可以像上面的用户那样使用将 i 作为参数的包装函数来执行此操作,或者更简单,我们可以将 i 的值作为默认值传递。现在我们附加了 3 个不同的 print(i) 函数,每个函数都有自己的默认值,即 for 循环中那一刻 i 的值。

def make_functions():
    flist = []

    for i in [1, 2, 3]:
        def print_i(i=i):
            print(i)
        flist.append(print_i)

    return flist

functions = make_functions()
for f in functions:
    f()