Python - 闭包



什么是闭包?

Python 闭包是一个嵌套函数,它可以访问来自封闭函数的变量,而封闭函数已经完成了执行。此类变量未绑定在局部作用域中。要使用不可变变量(数字或字符串),我们必须使用 nonlocal 关键字。

Python 闭包的主要优势在于,它可以帮助避免使用全局值并提供某种形式的数据隐藏。它们用于 Python 装饰器。

闭包与嵌套函数密切相关,并允许内部函数捕获并保留封闭函数的局部状态,即使外部函数已完成执行或作用域不再可用。理解闭包需要熟悉嵌套函数、变量作用域以及 Python 如何处理函数对象。

  • 嵌套函数:在 Python 中,函数可以在其他函数内部定义。这些称为嵌套函数或内部函数。
  • 访问封闭作用域:内部函数可以访问封闭(即外部)作用域中的变量。这就是闭包发挥作用的地方。
  • 状态保留:当内部函数(即闭包)捕获并保留来自其封闭作用域的变量时,即使外部函数已完成执行或作用域不再可用。

嵌套函数

Python 中的嵌套函数是指在一个函数内部定义另一个函数的做法。这个概念允许我们更有效地组织代码、封装功能和管理变量作用域。

以下是嵌套函数的示例,其中函数B在函数A内部定义。然后从外部函数的作用域内部调用内部函数。

示例

def functionA():
   print ("Outer function")
   def functionB():
      print ("Inner function")
   functionB()

functionA()

输出

Outer function
Inner function

如果外部函数接收任何参数,则可以将其传递给内部函数,如下例所示。

def functionA(name):
   print ("Outer function")
   def functionB():
      print ("Inner function")
      print ("Hi {}".format(name))
   functionB()
   
functionA("Python")

输出

Outer function
Inner function
Hi Python

变量作用域

当创建闭包(即捕获其封闭作用域中变量的内部函数)时,它会保留对这些变量的访问权限,即使外部函数已完成执行。这种行为允许闭包“记住”和操作封闭作用域中变量的值。

示例

以下是对闭包使用变量作用域的示例:

def outer_function(x):
    y = 10
    
    def inner_function(z):
        return x + y + z  # x and y are captured from the enclosing scope
    
    return inner_function

closure = outer_function(5)
result = closure(3)
print(result)  

输出

18

创建闭包

在 Python 中创建闭包涉及在外部函数中定义一个嵌套函数并返回内部函数。闭包对于捕获和保留来自封闭作用域的变量状态很有用。

示例

在下面的示例中,我们有一个 **functionA** 函数,它创建并返回另一个函数 **functionB**。嵌套的 **functionB** 函数是闭包。

外部 **functionA** 函数返回一个 **functionB** 函数并将其分配给 myfunction 变量。即使它已经完成了执行。但是,printer 闭包仍然可以访问 name 变量。

以下是使用 Python 创建闭包的示例:

def functionA(name):
   name ="New name"
   def functionB():
      print (name)
   return functionB
   
myfunction = functionA("My name")
myfunction()

输出

New name

nonlocal 关键字

在 Python 中,nonlocal 关键字允许访问局部作用域之外的变量。这用于闭包修改存在于外部变量作用域中的不可变变量。以下是带有 nonlocal 关键字的闭包示例。

def functionA():
   counter =0
   def functionB():
      nonlocal counter
      counter+=1
      return counter
   return functionB

myfunction = functionA()

retval = myfunction()
print ("Counter:", retval)

retval = myfunction()
print ("Counter:", retval)

retval = myfunction()
print ("Counter:", retval)

输出

Counter: 1
Counter: 2
Counter: 3
广告