📜  Python闭包(1)

📅  最后修改于: 2023-12-03 15:04:42.469000             🧑  作者: Mango

Python闭包

闭包(Closure)是指函数能够访问定义在其外部函数的一个非全局变量,即使外部函数已经返回。这个非全局变量可以是一个变量、函数或者对象等。在 Python 中,函数是第一类对象,因此可以将函数定义在另一个函数内部。

闭包的定义

一个包含注释的例子:

def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

closure = outer_function(10)
result = closure(5)
print(result)  # 15

在这个例子中,我们定义了一个外部函数 outer_function,该函数带有一个参数 x。我们内部定义了一个函数 inner_function,它带有一个参数 y,并返回 x + y 的结果。

在外部函数 outer_function 中,我们返回了内部函数 inner_function,而不是直接返回 x + y 的结果。因此,当外部函数被调用时,它将返回一个闭包——即一个包含嵌套函数和引用了外部函数中变量的环境的对象。

当我们调用外部函数时,它返回的就是 inner_function,但是 inner_function 仍然可以访问在 outer_function 中定义的 x 变量,因此其调用时可以使用前一次调用的结果。这个 x 变量就像是函数的私有成员变量。

在上面的代码中,我们首先调用 outer_function 并传递参数 10,将其结果保存在变量 closure 中。然后,我们对这个闭包调用 closure(5),返回结果为 15

闭包的应用

闭包可以用于许多场景,包括模拟私有变量、实现装饰器模式、编写工厂函数等等。下面举几个例子:

模拟私有变量

通过在函数中定义变量并返回内部函数,我们可以模拟出私有变量的概念,即只有内部函数才能访问某些变量。

def private_variable():
    count = 0
    def inner():
        nonlocal count  # 必须使用 nonlocal 关键字来声明 count 不是一个局部变量
        count += 1
        return count
    return inner

counter = private_variable()
print(counter())  # 1
print(counter())  # 2
print(counter())  # 3

在这个例子中,我们定义了一个私有变量 count,并将其定义在了 private_variable 函数内。我们返回了一个内部函数 inner,它对私有变量进行了修改。由于闭包的特性,外部无法直接访问 count 变量。

实现装饰器模式

使用闭包还可以方便地实现装饰器模式。我们可以用一个闭包将被装饰函数包装起来,并在外部添加一些额外的逻辑。

def my_decorator(func):
    def inner(x, y):
        print("Before the function is called.")
        result = func(x, y)
        print("After the function is called.")
        return result
    return inner

@my_decorator
def add(x, y):
    return x + y

print(add(1, 2))  # 3

在这个例子中,我们定义了一个装饰器函数 my_decorator,它带有一个参数 func,即被装饰的函数。我们返回了一个闭包 inner,它对 func 进行了包装,并在外面添加了一些逻辑。最后,我们使用 @my_decoratoradd 函数装饰起来,并调用它。

编写工厂函数

最后,我们来看一个使用闭包实现工厂函数的例子。我们可以定义一个函数,该函数返回一个新的函数,将其绑定到一个类或对象的方法中,从而实现类或对象的定制操作。

def make_multiplier(x):
    def multiplier(n):
        return x * n
    return multiplier

double = make_multiplier(2)
triple = make_multiplier(3)

print(double(5))  # 10
print(triple(5))  # 15

在这个例子中,我们定义了一个工厂函数 make_multiplier,它带有一个参数 x,即我们要乘的数。我们返回了一个新的函数 multiplier,它带有一个参数 n,即我们要乘的倍数。最后,我们可以使用 make_multiplier 来创建一个 double 函数和一个 triple 函数,并将它们分别传递给其他函数。

结语

Python 中的闭包是一项强大而灵活的技术,它可以帮助我们编写更清晰、更可维护的代码。掌握闭包的概念和应用将有助于您在编写 Python 代码时更好地使用这项技术。