Python中的嵌套函数如何工作?
def maker(n):
def action(x):
return x ** n
return action
f = maker(2)
print(f)
print(f(3))
print(f(4))
g = maker(3)
print(g(3))
print(f(3)) # still remembers 2
为什么嵌套的函数在 maker()
返回并退出后,仍然能记住最初的值 2
,当 action()
被调用时?
9 个回答
15
你定义了两个函数。当你调用
f = maker(2)
时,你实际上是在定义一个返回数字两倍的函数,所以
f(2) --> 4
f(3) --> 6
接着,你又定义了另一个不同的函数
g = maker(3)
这个函数返回数字的三倍
g(3) ---> 9
但是它们是两个不同的函数,并不是同一个函数。每个函数都是独立的。即使在函数'maker'内部,它们的名字是一样的,但它们并不是同一个函数。每次你调用maker()
时,实际上是在定义一个新的函数。这就像是一个局部变量,每次调用这个函数时,虽然名字相同,但可以包含不同的值。在这个例子中,变量'action'包含了一个函数(而且这个函数可能是不同的)。
40
你实际上是在创建一个闭包。
在计算机科学中,闭包是一个特殊的函数,它可以使用一些在外部定义的变量。这些变量在闭包创建时就被绑定在了它的环境中。我们说这个函数“封闭”了它所使用的外部变量。
相关阅读:闭包:它们为什么这么有用?
闭包其实就是一种更方便的方式,让一个函数可以访问到它外部的状态。
来自http://docs.python.org/reference/compound_stmts.html:
程序员注意:函数是第一类对象。在一个函数定义内部执行的'def'形式会定义一个局部函数,这个函数可以被返回或传递。嵌套函数中使用的自由变量可以访问包含这个'def'的函数的局部变量。有关详细信息,请参见命名和绑定部分。
33
你可以把它理解为,父函数里的所有变量在子函数中都被替换成了它们的实际值。这样,子函数就不需要去关注父函数的范围,就能正常运行。
可以把它看作是“动态创建一个函数”。
def maker(n):
def action(x):
return x ** n
return action
f = maker(2)
--> def action(x):
--> return x ** 2
这是Python的基本行为,它在多个赋值时也会这样做。
a = 1
b = 2
a, b = b, a
Python是这样理解的:
a, b = 2, 1
它基本上是在对这些值进行任何操作之前,先把它们插入进去。