引言:一个看似简单却暗藏玄机的概念
在Python编程中,闭包(closure)是一个既基础又高级的概念。新手可能觉得它神秘莫测,而有经验的开发者则视其为得力助手。今天,我们就来揭开这个"小妖精"的神秘面纱。
初识闭包------它是什么?
1.1 最简单的闭包示例
python
def outer_func():
message = "Hello"
def inner_func():
print(message)
return inner_func
my_func = outer_func()
my_func() # 输出: Hello
这个简单的例子展示了闭包的核心特征:内部函数记住了外部函数的变量,即使外部函数已经执行完毕。
1.2 闭包的正式定义
闭包是指一个函数(内部函数)与其相关的引用环境(外部函数的局部变量)的组合。它有三个特点:
- 嵌套函数结构
- 内部函数引用外部函数的变量
- 外部函数返回内部函数
为什么需要闭包?
2.1 数据封装
闭包提供了一种轻量级的封装方式,不需要类就能实现数据的隐藏和保护。
python
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
c = counter()
print(c()) # 1
print(c()) # 2
print(c()) # 3
nonlocal count
:申明使用外部变量,如果内部函数存在赋值的情况需要此申明,具体的可以查看变量作用域文章
2.2 保持状态
在函数式编程中,闭包是保持状态的主要方式之一,避免了全局变量的使用。
闭包的工作原理
3.1 闭包的__closure__属性
python
def outer(x):
def inner(y):
return x + y
return inner
closure = outer(10)
print(closure.__closure__) # 包含cell对象的元组
print(closure.__closure__[0].cell_contents) # 10
__closure__
: 所有函数都有一个__closure__
属性,如果函数是闭包的话,那么它返回的是一个由 cell 组成的元组对象cell_contents
: cell 对象的cell_contents
属性就是存储在闭包中的变量。
闭包的陷阱与注意事项
4.1 延迟绑定问题
python
functions = []
for i in range(3):
def func():
return i
functions.append(func)
print([f() for f in functions]) # [2, 2, 2] 而不是预期的[0, 1, 2]
解决方案:
python
functions = []
for i in range(3):
def func(i=i): # 使用默认参数捕获当前值
return i
functions.append(func)
4.2 内存消耗
闭包会保持外部变量的引用,可能导致意外的内存占用。
结语
点个赞,关注我获取更多实用 Python 技术干货!如果觉得有用,记得收藏本文!