有人能解释一下 Python 中函数的关闭吗?

时间:2021-06-25 09:17:50

标签: python closures higher-order-functions

Python

谁能帮我理解这段代码,我是 Python 新手,这个函数是如何工作的?

    def makeInc(x):
        def inc(y):

            return y + x
        return inc
    incOne = makeInc(1)
    incFive = makeInc(5)
    print(incOne(5)) # returns 6
    print(incFive(5)) # returns 10

2 个答案:

答案 0 :(得分:1)

高阶函数


makeInc 这样的函数又返回另一个函数,称为 higher order functions。通常,已知函数接受数据作为输入并返回数据作为输出。对于高阶函数,函数而不是数据,要么返回代码作为输出,要么接受代码作为输入。这段代码被包装成一个函数。在 Python 中,函数是一等公民,这意味着函数就像数据一样可以传递。例如:

myvariable = print

请注意,我如何将 print 分配给 myvariable 以及我如何在 print 之后去掉括号 没有括号的函数称为函数对象。这意味着 myvariable 现在只是 print 的另一个名称:

print("Hello World!")
myvariable("Hello World!")

以上两个语句都做完全相同的事情。可以分配给变量的也可以从函数返回:

def myfunction():
    return print


myfunction()("Hello World!");

现在让我们看看你的例子:

def makeInc(x):
    def inc(y):

        return y + x
    return inc

makeInc 是一个函数,它接受一个名为 x 的参数。然后它定义了另一个名为 inc 的嵌套内部函数,它接收一个名为 y 的参数。关于嵌套函数的事情是它们也可以访问封闭函数的变量。这里,inc 是内部函数,但它可以访问 x,它是封闭外部作用域的变量。 最后一条语句 return inc 将内部函数返回给 makeInc 的调用者。 makeInc 本质上所做的是根据它接收到的参数创建一个自定义函数。 例如:

x = makeInc(10)

makeInc 将首先接受 10,然后返回一个接受参数 y 并将 y 增加 10 的函数。 此处,x 是一个函数,它接受任何参数 y,然后将其递增 10:

x(42) # Returns 52

nonlocal

但是,在使用嵌套函数时有一个警告:

def outer():
    x = 10
    def inner():
       x = 20
    inner() 
    print(x) # prints 10

在这里,您假设最后一个 print 语句将打印 20。但不是!当您在内部函数中分配 x = 20 时,它会创建一个名为 x 的新局部变量,该变量被初始化为 20。外部 x 保持不变。要修改外部 x,请使用 nonlocal 关键字:

def outer():
    x = 10
    def inner():
       nonlocal x = 20
    inner()
    print(x) # prints 20

如果直接读取 x 内的 inner() 而不是赋值给它,则不需要 nonlocal

答案 1 :(得分:0)

这里发生的是 makeInc() 返回一个指向 inc() 特定实现的函数句柄。因此,调用 makeInc(5) 会将 x 中的 inc(y)“替换”为 5 并返回该函数的可调用句柄。此句柄保存在 incFive 中。您现在可以调用定义的函数 (inc(y))。由于您之前设置了 x=5,结果将是 y+5