Python中不同类型的闭包及其应用
更新时间:2023-12-01什么是闭包
在计算机科学中,闭包是一种函数和其相关引用环境的组合,通过闭包可以让函数访问其被定义时的作用域。简单来说,闭包是一种可以访问其他函数内部变量的函数。
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
result = outer_function(5)
print(result(3))
在这个例子中,`outer_function()`嵌套定义了`inner_function()`,`inner_function`中访问了`outer_function`的参数`x`,并将其与传递给自己的参数`y`相加。调用`outer_function(5)`返回`inner_function`,然后将其分配给变量`result`。现在调用`result(3)`,它返回`5 + 3`,即`8`,因为`inner_function`访问了`outer_function`的变量。
非局部变量
在闭包中,访问其他函数变量的方式不仅限于函数参数,还可以使用Python的“非局部”变量。
def outer_function(x):
def inner_function(y):
nonlocal x
x += 1
return x + y
return inner_function
result = outer_function(5)
print(result(3))
在这个例子中,`nonlocal x`声明了`x`是外部函数(即`outer_function`)的变量,并在`inner_function`中更新`x`的值。调用`result(3)`将返回`6 + 3 = 9`,因为`x`的值已经在`inner_function`中改变。
通过闭包缓存值
闭包经常被用来实现简单的缓存,其中闭包“记住”了函数的输入和输出,而不是每次重新计算函数。
def fibonacci():
cache = {}
def fibonacci_recursive(n):
if n in cache:
return cache[n]
elif n == 0:
result = 0
elif n == 1:
result = 1
else:
result = fibonacci_recursive(n-1) + fibonacci_recursive(n-2)
cache[n] = result
return result
return fibonacci_recursive
fib = fibonacci()
print(fib(6))
在这个例子中,`fibonacci()`函数返回`fibonacci_recursive()`闭包,能够计算斐波那契数列。`cache`字典用来存储之前计算过的结果,如果输入已经在`cache`中则无需重新计算,直接返回之前的结果。调用`fib(6)`时,它使用存储在缓存中的结果计算斐波那契数列的第6项,返回`8`。
使用闭包实现修饰器
闭包也可以用于实现修饰器,修饰器的作用是可以在不改变原函数代码的情况下,给函数增加额外的功能。
def debug(func):
def wrapper(*args, **kwargs):
print("函数正在执行:", func.__name__)
return func(*args, **kwargs)
return wrapper
@debug
def add(num1, num2):
return num1 + num2
print(add(3, 5))
在这段代码中,`debug`函数是一个装饰器工厂函数,它定义了一个带有内部函数`wrapper`的闭包, `wrapper`接受任意参数并且调用它的宿主函数,同时在宿主函数执行前输出一条信息。使用`@debug`语法来修饰`add`函数,此时`add`函数已经成为被`debug`装饰过的函数,并且调用`add(3,5)`时,将输出以下内容:
函数正在执行: add
8