【问题标题】:Can anybody explain about the closure of function in Python?任何人都可以解释 Python 中函数的闭包吗?
【发布时间】:2021-09-08 16:51:25
【问题描述】:

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

【问题讨论】:

  • 也许这有助于Why aren't python nested functions called closures?(适用于 Python 2,但该参数应适用于 Python 3)。
  • 您的 makeInc 函数将 inc 函数作为值返回,因此当您将第一个函数调用为 incOne = makeInc(1) 时,它将 x 的值设置为 1,并在您调用时返回您的 inc 函数以再次从 incOne var 调用incOne(5) 它设置 y =5 并计算 x 和 y 的和并返回值。它被称为嵌套函数

标签: python closures higher-order-functions


【解决方案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

如果你直接在inner()里面读取x而不是赋值给它,你就不需要nonlocal

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2016-01-14
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 2019-06-02
      • 2015-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多