闭包调用的步骤:
**1.调用外部函数:**创建闭包实例(返回内部函数);
**2.通过闭包实例调用内部函数:**执行闭包逻辑,访问外部变量。
基础调用实例
1.无参数闭包
python
def outer():
x = 10
def inner():
print(x)
return inner
# 步骤1:调用外部函数,获取闭包实例
closure = outer()
# 步骤2:调用闭包(内部函数)
closure() # 输出:10(访问外部变量x)
2.带参数闭包
python
def make_greeter(greeting):
def greeter(name):
return f"{greeting}, {name}!"
return greeter
# 创建闭包实例(指定问候语)
greeter_zh = make_greeter("你好")
greeter_en = make_greeter("Hello")
# 调用闭包(传递参数)
print(greeter_zh("小明")) # 输出:你好, 小明!
print(greeter_en("Alice")) # 输出:Hello, Alice!
闭包的参数传递方式
1.外部函数参数
通过外部函数的参数传递"固定值",闭包内部函数使用该值:
python
def make_power(exponent):
def power(base):
return base ** exponent
return power
# 创建闭包(平方函数)
square = make_power(2)
print(square(5)) # 输出:25
# 创建闭包(立方函数)
cube = make_power(3)
print(cube(5)) # 输出:125
2.内部函数参数
闭包内部函数的参数在调用时传递:
python
def make_counter(initial=0):
count = initial
def counter(increment=1):
nonlocal count
count += increment
return count
return counter
# 创建闭包(初始值为0)
counter = make_counter()
print(counter()) # 输出:1(默认增加1)
print(counter(5)) # 输出:6(增加5)
闭包的状态保持
闭包会记住外部变量的状态,多次调用会持续修改:
python
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
# 创建闭包实例
counter = make_counter()
print(counter()) # 输出:1
print(counter()) # 输出:2
print(counter()) # 输出:3
闭包调用的高级技巧
1.闭包作为装饰器
python
def decorator(func):
def wrapper():
print("执行前")
func()
print("执行后")
return wrapper
@decorator
def greet():
print("Hello!")
# 调用闭包(装饰后的函数)
greet() # 输出:
# 执行前
# Hello!
# 执行后
2.闭包与回调函数
python
def async_task(callback):
def execute():
print("执行异步任务...")
callback() # 调用闭包回调
return execute
# 创建闭包回调
def on_success():
print("任务成功!")
# 创建异步任务实例
task = async_task(on_success)
task() # 输出:
# 执行异步任务...
# 任务成功!
常见调用问题与解决方案
1.未正确调用外部函数
python
def outer():
x = 10
def inner():
print(x)
return inner
# 错误:直接调用内部函数(无法访问外部变量)
outer().inner() # 报错:AttributeError(outer()返回的是函数,不是对象)
# 正确调用方式
closure = outer()
closure() # 输出:10
2.循环变量闭包陷阱
python
def make_callbacks():
callbacks = []
for i in range(3):
callbacks.append(lambda: print(i)) # 闭包捕获的是循环变量i的最终值
return callbacks
callbacks = make_callbacks()
for cb in callbacks:
cb() # 全部输出:2(错误)
# 解决方案:用默认参数绑定当前值
def make_callbacks():
callbacks = []
for i in range(3):
callbacks.append(lambda i=i: print(i)) # 默认参数保存当前i的值
return callbacks
callbacks = make_callbacks()
for cb in callbacks:
cb() # 输出:0, 1, 2(正确)
3.修改外部变量失败
python
def outer():
x = 10
def inner():
x += 1 # 错误:x被视为局部变量
return inner
closure = outer()
closure() # 报错:UnboundLocalError
# 解决方案:使用nonlocal声明
def outer():
x = 10
def inner():
nonlocal x
x += 1
print(x)
return inner
closure = outer()
closure() # 输出:11
闭包调用
**1.明确闭包职责:**闭包应专注于封装状态或延迟计算;
**2.参数传递清晰:**通过外部函数传递固定函数,内部函数处理可变参数;
**3.及时释放资源:**避免闭包引用大对象,必要时手动解除引用:
python
def outer():
large_data = [1] * 1000000
def inner():
return sum(large_data)
return inner
closure = outer()
del closure # 手动释放闭包引用