Python闭包原理与常见陷阱解析
本文深入解析Python中闭包的定义与工作机制,重点剖析循环中返回函数时变量引用导致的常见错误。通过对比错误代码与修正方案,阐明如何利用参数绑定解决循环变量共享问题,为理解装饰器及高级函数编程奠定基础。
闭包概念概述
一、闭包概念概述
闭包的核心定义在于:当内部函数引用了外部函数的参数或局部变量,且该内部函数作为返回值被返回时,这些外部变量和参数会随同内部函数一起被保存下来。这种将变量与函数绑定在一起的结果,即被称为闭包。
在前文连载的第17部分中,示例函数myF4展示了这一机制的典型应用。
闭包常见陷阱与解决方案
三、闭包使用中常见的误区
def count():
#定义列表
fs = []
for i in range(1, 4):
def f():
return i * i
fs.append(f)
# 按照我们的预期, 应该是fs = [f, f, f].其中f中一次包含1, 4, 9, 这样才对, 但实际结果不是, 我么接着看
return fs
f1, f2, f3 = count()
print(f1(), f2(), f3())

预期的输出结果并非1、4、9。
(1)原因剖析:返回的函数实际上引用的是变量i,但i并未在定义时立即执行。直到三个函数全部返回后,才统一执行计算,此时变量i的值已变为3,因此最终调用时返回的是3*3的结果。
(2)核心结论:在返回闭包时,内部函数不应直接引用任何循环变量。
(3)解决策略:引入一个额外的函数,利用该函数的参数来绑定循环变量的当前值。由于参数在调用时即被固定,无论后续循环变量如何变化,已绑定的函数参数值保持不变。
改进后的代码如下:
def count2():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1,4):
fs.append(f(i))
#我们进行了传参,因此j就固定下来,它就执行了j
return fs
f4,f5,f6 = count2()
print(f4(),f5(),f6())

装饰器与源码参考
二、装饰器简介
def hello():
print("我是一个程序")
f = hello
f()
hello()
#用id来证明f和hello是一个函数
print(id(f),id(hello))

三、完整源代码
项目目录:d20_2_closure_interpretation
代码仓库地址:https://github.com/ruigege66/Python_learning/blob/master/d20_2_closure_interpretation
文中通过详细的示例代码进行了介绍,对读者的学习或工作具有较高的参考价值。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













