使用for循环创建的lambda函数是否属于Python闭包?
问题解答
1. 原代码是否创建了闭包?
没有。闭包的核心是嵌套在另一个函数中的内部函数,且能访问并保留外层函数作用域中的变量引用。而原代码中的lambda直接定义在全局作用域,并非嵌套在某个外层函数内部,完全不满足闭包的“嵌套函数”前提。
2. n是闭包的自由变量还是全局变量?
n是全局变量。因为lambda定义在全局作用域,它引用的n是全局命名空间中的变量,而非外层函数的局部变量。这一点可以从你打印的结果得到验证:
a.__closure__返回None:闭包函数的__closure__属性会包含保存外层变量引用的cell对象,非闭包函数则为None。a.__code__.co_freevars返回空元组():该属性存储函数引用的自由变量(即外层作用域但非全局作用域的变量),空元组说明没有这样的变量。
3. 为什么输出都是4?
lambda对变量的引用是延迟绑定的——直到函数被调用时,才会去查找变量的值。原代码中循环结束后,全局变量n的值已经变成3,所以每个lambda调用f(1)时,都会计算1+3,最终输出三个4。
真正的闭包示例
如果要创建闭包,需要把lambda嵌套在一个外层函数中,让n成为外层函数的局部变量:
def generate_funcs(): funcs = [] for n in range(1, 4): # 用默认参数绑定当前循环的n值,避免延迟绑定问题 funcs.append(lambda x, current_n=n: x + current_n) return funcs funcs = generate_funcs() for f in funcs: print(f(1)) # 输出 2 3 4
此时查看函数的属性:
a = funcs[1] print(a.__closure__) # 会包含cell对象,非None print(a.__code__.co_freevars) # 输出 ('current_n',)
这才是符合定义的闭包:内部函数(lambda)嵌套在外层函数中,且引用了外层函数的变量,即使外层函数执行完毕,内部函数仍能保留该变量的引用。
内容的提问来源于stack exchange,提问作者alixi6
相关产品推荐
相关产品推荐

