Python 闭包
要了解python闭包,您应该具有嵌套函数和python类的想法。
实际上,python闭包也是一个提供了使用代码封装某些数据的机会的功能。
Python嵌套函数
def funcOut(): print("Now we are in funcOut.") def funcIn(): print("This function is defined inside the funcOut.\nThis one is called a nested Function.") print("Here we will call the funcIn that is defined.") funcIn() print("We are in _main_.\nCalling the funcOut.") funcOut()
在上面的代码中,funcIn
是嵌套在funcOut
中的函数。
如果您看上面代码的输出,那么您将了解函数的调用顺序。
输出将是:
We are in _main_. Calling the funcOut. Now we are in funcOut. Here we will call the funcIn that is defined. This function is defined inside the funcOut. This one is called a nested Function.
将funcOut变成python闭包
假设您想拥有funcOut中的funcIn完成的所有功能。
你该怎么做?你在想什么?
返回值
通常,我们从函数返回值或者引用。
但是其中我们需要返回funcIn
的全部功能。
如果我们仅用return funcIn
覆盖第6行中调用funcIn()
的函数,那么我们已经实现了我们想要的。
我们刚刚做的事情被称为python中的闭包。
在阅读整个教程时,您将更清楚地了解python闭包。
Python闭包的想法
因此,从以上内容我们了解到,当一个函数返回其中定义的另一个函数(即嵌套函数)时,称为闭包。
现在让我们看一下闭包的示例结构。
Python闭包结构
def closureFunc(): def nestedFunc(): # ... statements ... print(" Welcome To Closure ") return nestedFunc get = closureFunc() get()
这将输出:
Welcome To Closure
在上面的代码中,按照函数的名称,希望您理解外部函数是闭包函数,其中有一个嵌套函数,闭包函数将返回该函数。
Python闭包将代码嵌入代码
当我们创建一个类的对象时,该对象包含一些信息。
就像该闭包将数据嵌入代码中一样。
让我们用示例代码进行探索
def closureFunc(n): def nestedFunc(): # ... statements .. print("Welcome To Closure ") print("You have sent argument %d + 10 = %d" % (n, n+10)) return nestedFunc getting = closureFunc(12) getting()
这将输出:
Welcome To Closure You have sent argument 12 + 10 = 22
注意第7行和第8行– getting变量现在可以作为函数使用。
嵌套函数的内部函数的所有功能现在都由它完成。
Python Closure记住了它的上下文
看下面的代码,我们已经删除了closureFunc
。
def closureFunc(sum): def nestedFunc(): # ... statements .. print("Welcome To Closure ") print("You have sent argument %s" % sum) return nestedFunc getting = closureFunc(12) del closureFunc getting()
这将输出:
Welcome To Closure You have sent argument 12
这就是闭包的力量。
即使删除了闭包函数," getting"也会记住它的上下文以及它的作用。
这就是为什么即使删除实际函数也得到" getting"输出的原因。
在闭包中使用非局部变量
让我们来看另一个例子。
下面的闭包将所有数字加到一个特定范围内,这是闭包函数的参数。
def closureFunc(up): val = 0 def nestedFunc(): nonlocal val print("Welcome To Closure ") for i in range(up+1): val += i print("Total is = %d" % val) return nestedFunc getting = closureFunc(5) getting()
这将输出:
Welcome To Closure Total is = 15
注意,我们在closureFunc中使用了一个变量val,并在nestedFunc
中重用了它,并使用关键字nonlocal
声明为该函数的非本地变量。
如果您未声明为非本地变量,则会在分配之前引用本地变量val的错误提示,这意味着它将被视为nestedFunc函数的局部变量。
带参数的闭包
让我们看一下本教程的最后一个示例。
在此代码中,我们想为nestedFunc提供参数。
并观察输出的不同值。
def closureFunc(up): val = 0 def nestedFunc(arg): nonlocal val print("Welcome To Closure ") for i in range(up+1): val += i val *= arg print("Total is = %d" % val) return nestedFunc retFunc = closureFunc(5) retFunc(10) retFunc(4)
下图显示了以上python关闭程序的输出。
如果您能理解为什么第二个输出是660,那么我必须说您已经从本教程中学到了知识。
输出为660,因为在执行第11行时,设置了变量up = 5。
然后,当执行第12行时,执行" nestedFunc",并设置变量val = 150。
之后,当我们在第13行再次使用不同的参数4调用函数时,closureFunc的up = 5,val = 150。
因此,在for循环中,val将更新150,再加上1到5的总和,等于150 + 15 =165。
然后将其乘以4,等于660。
就是这样。
这就是python闭包。
希望本教程对您有所帮助。
最好的运气编码与闭包。
__closure__
所有函数对象都有一个__closure__元组属性,如果它是一个闭包函数,则返回单元格对象。
def closureFunc(up): val = 0 def nestedFunc(arg): nonlocal val print("Welcome To Closure ") for i in range(up + 1): val += i val *= arg print("Total is = %d" % val) return nestedFunc retFunc = closureFunc(5) print(retFunc.__closure__) print(retFunc.__closure__[0].cell_contents) print(retFunc.__closure__[1].cell_contents) retFunc(10) print(retFunc.__closure__) print(retFunc.__closure__[0].cell_contents) print(retFunc.__closure__[1].cell_contents) retFunc(4) print(retFunc.__closure__) print(retFunc.__closure__[0].cell_contents) print(retFunc.__closure__[1].cell_contents)
现在将产生以下输出,并且闭包上下文值up和val也将被打印。
(<cell at 0x10079f288: int object at 0x10028ba80>, <cell at 0x101033618: int object at 0x10028b9e0>) 5 0 Welcome To Closure Total is = 150 (<cell at 0x10079f288: int object at 0x10028ba80>, <cell at 0x101033618: int object at 0x10028cca0>) 5 150 Welcome To Closure Total is = 660 (<cell at 0x10079f288: int object at 0x10028ba80>, <cell at 0x101033618: int object at 0x1007eae70>) 5 660
Python闭包是一个很好的功能,但是如果我们有更多内部函数和参数,它将变得复杂。
您可以使用类和常规函数来实现相同的目的。
因此请谨慎使用python闭包。