Python 的闭包,你知道多少?一起聊聊

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益:

  1. 了解大厂经验
  2. 拥有和大厂相匹配的技术等

一、前言

看到了很多函数套函数的函数,总之对于 Java 的宝宝来说,没有见过的稀奇,比如:

python 复制代码
def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling function: {func.__name__}")
        result = func(*args, **kwargs)
        print(f"Function {func.__name__} executed")
        return result
    return wrapper

经过多方搜寻,才知道这是闭包

二、闭包

2.1 闭包简介

wiki 上对闭包的解释

In programming languages, a closure , also lexical closure or function closure , is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function[a] together with an environment.[1] The environment is a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or reference to which the name was bound when the closure was created.[b] Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.

简单点来说就是 闭包是指一个函数内部定义的函数,并且内部函数引用了外部函数的变量

2.2 闭包优势

在Python中,这样可以使代码更整洁和可读性更好。然而,函数嵌套提供了一种更高级的编程技术,它具有一些独特的优势和用途,比如:

  1. 封装和信息隐藏:函数嵌套可以用于封装和隐藏实现细节。外层函数可以定义一些内部函数,对外部代码隐藏内部实现逻辑,提供抽象的接口。这样可以降低代码的复杂性,使代码更模块化和可维护。
  2. 限制作用域:函数嵌套可以创建一个新的作用域。内层函数可以访问外层函数的变量和参数,但外部代码无法直接访问这些变量。这种限制作用域的方式可以保护变量免受外部代码的意外修改,提高代码的安全性和可靠性。

2.3 更多的闭包举例

当涉及到函数嵌套的使用场景时,以下是一些具体的例子来说明每个场景:

  1. 闭包:
python 复制代码
def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

add_five = outer_function(5)
result = add_five(3)  # 返回 8

在这个例子中,outer_function 是外层函数,它接受一个参数 x 并定义了内层函数 inner_functioninner_function 使用外层函数的参数 x 来执行加法运算。通过调用 outer_function 并传入参数 5,我们创建了一个闭包 add_five,它可以在之后的调用中记住 x 的值,并与传入的参数进行相加。

  1. 封装和信息隐藏:
python 复制代码
def calculator():
    def add(x, y):
        return x + y

    def subtract(x, y):
        return x - y

    return add, subtract

add_func, subtract_func = calculator()
result = add_func(5, 3)  # 返回 8

在这个例子中,calculator 是外层函数,它定义了两个内层函数 addsubtract。通过调用 calculator,我们可以获得这两个函数的引用并在之后的代码中使用它们。这样可以隐藏实现细节,使代码更清晰和可维护。

  1. 辅助函数:
python 复制代码
def validate_input(value):
    def is_positive():
        return value > 0

    def is_even():
        return value % 2 == 0

    if is_positive() and is_even():
        print("输入是正数且是偶数")
    else:
        print("输入不满足要求")

validate_input(10)  # 输出: 输入是正数且是偶数
validate_input(-5)  # 输出: 输入不满足要求

在这个例子中,validate_input 是外层函数,它包含了两个内层函数 is_positiveis_even。这些辅助函数被用于验证输入值的特定条件。通过在外层函数中定义这些辅助函数,可以提高代码的可读性和可维护性。

  1. 递归:
python 复制代码
def factorial(n):
    if n <= 1:
        return 1
    else:
        return n * factorial(n - 1)

result = factorial(5)  # 返回 120

在这个例子中,factorial 函数是一个递归函数,它在内部调用自身来计算阶乘。通过不断调用内层函数,逐步解决较小的问题,最终达到解决整个问题的目的。

这些例子展示了函数嵌套在不同场景下的具体应用。函数嵌套的灵活性使其适用于许多编程任务和问题。通过合理地使用函数嵌套,可以提高代码的可读性、可维护性和复用性。

三、总结

本文详细介绍了闭包在计算机编程中的概念和应用。闭包可以通过在函数内部定义函数并引用外部函数的变量来实现词法作用域中的名称绑定。闭包具有封装和信息隐藏、限制作用域等优势,并可以应用于多种编程任务和问题。通过合理地使用闭包,可以提高代码的可读性、可维护性和复用性。

相关推荐
m0_748554814 小时前
golang如何实现用户订阅偏好管理_golang用户订阅偏好管理实现总结
jvm·数据库·python
smj2302_796826525 小时前
解决leetcode第3911题.移除子数组元素后第k小偶数
数据结构·python·算法·leetcode
小码哥_常5 小时前
解锁AI编程密码:程序员常用的10个AI提示词
后端
阿正呀6 小时前
Redis怎样实现本地缓存的高效失效通知
jvm·数据库·python
2501_901200536 小时前
mysql如何设置InnoDB引擎参数_优化innodb_buffer_pool
jvm·数据库·python
_.Switch6 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战
开发语言·前端·javascript·网络·爬虫·python·ecmascript
Mr_sst6 小时前
Claude Code 部署与使用保姆级教程(2026 最新)
python·ai
直奔標竿6 小时前
Java开发者AI转型第二十七课!Spring AI 个人知识库实战(六)——全栈闭环收官,解锁前端流式渲染终极技巧
java·开发语言·前端·人工智能·后端·spring
瞎某某Blinder6 小时前
DFT学习记录[6]基于 HES06的能带计算+有效质量计算
python·学习·程序人生·数据挖掘·云计算·学习方法
金銀銅鐵7 小时前
[java] 编译之后的记录类(Record Classes)长什么样子(上)
java·jvm·后端