python中的闭包
在 Python 中,闭包是一个由另一个函数返回的函数,且这个返回的函数不仅能够访问其在创建时的作用域中的变量,还能够捕获和保存这些变量,即使外部作用域已经结束了。
1.闭包的常见用途
最常见的用途:是创建只有函数能够访问的私有变量或函数。这可以用来存储状态或数据,而无需使用全局变量。
以下是闭包的一些关键特性:
- 必须有一个内嵌函数。
- 内嵌函数需要引用外部函数中的变量。
- 外部函数必须返回内嵌函数。
下面是一个创建闭包的简单例子:
def outer_function(msg):
# 这是外部函数,它定义了一个变量 msg
def inner_function():
# 这是内嵌函数,它访问了外部函数的变量 msg
print(msg)
return inner_function # 返回内嵌函数,这里创建了闭包
# 使用闭包
my_closure = outer_function('Hello, World!')
my_closure() # 输出: Hello, World!
在这个例子中,outer_function
创建了一个变量 msg
,然后定义了一个内嵌的 inner_function
,它打印出 msg
变量的值。outer_function
返回 inner_function
,但不执行它。这样,即使 outer_function
的执行已经完成,msg
变量的值仍然被 inner_function
保留,因为 inner_function
闭包了(即,捕获并保存了)这个变量。
闭包在 Python 中是一个强大的概念,它允许你隐藏状态,创建装饰器,实现延迟计算等。理解闭包对于编写高效和优雅的 Python 代码非常重要。
2.装饰器在 Python 中是一个非常典型的闭包应用场景
装饰器本质上是一个函数,它接受一个函数作为参数并返回一个新的函数。返回的函数(通常称为“包装器”或“wrapper”)能够在原始函数被调用前后增加额外的行为(例如,日志记录、缓存、权限检查等),而不需要修改原始函数的定义。这个返回的函数闭包了(即,捕获并保存了)原始函数,因此即使在原始函数的上下文之外,装饰器返回的函数也能够访问和调用原始函数。
下面是一个使用闭包实现装饰器的例子:
def my_decorator(func):
def wrapper(*args, **kwargs):
print("Something is happening before the function is called.")
result = func(*args, **kwargs)
print("Something is happening after the function is called.")
return result
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
在这个例子中,my_decorator
是一个装饰器,它接受一个函数 func
并定义了另一个函数 wrapper
。wrapper
函数闭包了 func
,并在 func
被调用前后增加了额外的打印语句。最后,my_decorator
返回 wrapper
函数。
使用 @my_decorator
语法,我们实际上是将 say_hello
函数传递给了 my_decorator
,并将返回的 wrapper
函数赋值给 say_hello
。因此,当我们调用 say_hello()
时,实际上是在调用 wrapper
函数。
这个过程中,wrapper
函数作为闭包,保留了对 func
(在这个例子中是 say_hello
)的引用,这允许 wrapper
在其内部调用 func
,即使 func
的作用域已经结束。