淘先锋技术网

首页 1 2 3 4 5 6 7

Python闭包是什么?简单说,闭包就是定义在一个函数内部的函数,而这个函数可以访问外部函数的变量,即使外部函数已经返回了。

def outer_func(x):
def inner_func(y):
return x + y
return inner_func
closure = outer_func(10)
print(closure(5)) # 输出15,即10+5

在上面的例子中,我们定义了一个outer_func函数,它返回一个inner_func函数。当我们调用outer_func(10)时,它返回inner_func函数,并封装了x=10这一局部变量。我们将这个函数对象保存在closure变量中,这时我们就得到了一个闭包。然后我们调用closure(5),由于inner_func函数能够访问x这个变量,因此它将返回15。

闭包有什么用呢?一个常见的应用就是在装饰器中使用闭包实现函数的包装。比如我们想要给一个函数动态添加一些属性:

def add_attr(*attrs):
def decorator(func):
for attr in attrs:
setattr(func, attr, True)
return func
return decorator
@add_attr('is_admin', 'is_private')
def my_func():
pass
print(my_func.is_admin) # 输出True
print(my_func.is_private) # 输出True

在上面的例子中,我们定义了一个add_attr函数,它返回一个内部函数decorator。当@add_attr('is_admin', 'is_private')装饰了my_func函数时,Python会将my_func作为参数传给add_attr函数,并将'is_admin'和'is_private'作为参数传给decorator函数。decorator函数在遍历attrs时,使用setattr函数将属性设置到my_func中,最终返回my_func本身。因此我们可以使用my_func.is_admin和my_func.is_private来访问这些属性,而这些属性是在函数定义时动态添加的。

Python闭包在多线程编程中也有广泛的应用。例如,我们想要创建一个类似于Java的Runnable接口的函数,这个函数可以在子线程中运行,并返回一个结果:

import threading
def create_worker_func(func, *args, **kwargs):
def worker_func():
result = func(*args, **kwargs)
worker_func.result = result
worker_func.result = None
return worker_func
def my_func(x):
return x + 1
worker = create_worker_func(my_func, 5)
thread = threading.Thread(target=worker)
thread.start()
thread.join()
print(worker.result) # 输出6

在上面的例子中,我们定义了一个create_worker_func函数,它接受一个函数和可变参数,返回一个worker_func函数。当我们调用worker_func函数时,它会使用传入的函数、可变参数和关键字参数来计算结果,并将结果保存到worker_func.result属性中。由于worker_func函数是闭包,因此它可以在子线程运行,并持久保存结果。在主线程中调用print(worker.result)时,我们可以得到子线程计算的结果6。