当前位置: 首页 > article >正文

函数闭包的学习

一、闭包的概念,作用,条件

作用:可以保存外部函数的变量
形成条件:
1 函数嵌套 2 内部函数用了外部函数的变量或者参数
3 外部函数返回了内部函数(是返函数名,不带括号)
这个使用了外部函数变量的内部函数称为闭包。

口诀:函数嵌套,内用外参,外返内名。

例1:
def outer_function(x):
    def inner_function(y):
        return x + y  # 访问外部函数的局部变量 x
    return inner_function
# 创建闭包函数
inner = outer_function(10)
result1 = inner(5)  # 输出:15
例2:根据配置信息使用闭包实现不同人的对话信息。例如对话:
张三:到北京了吗?
李四:已经到了,放心吧。
def config_name(name):
    def inner(msg):
        print(f"{name}:{msg}")
    return inner
tom=config_name("Tom")
jerry=config_name("Jerry")
tom("我们一起玩耍")
jerry("我不去")
tom("来嘛来嘛")
jerry("打死都不去")
实现方式2:
def create_conversation(person_name, *lines):
    def conversation(partner_name):
        for i, line in enumerate(lines):
            if i % 2 == 0:
                print(f"{person_name}: {line}")
            else:
                print(f"{partner_name}: {line}")
    return conversation
# 创建对话闭包
tom_conversation = create_conversation("Tom", "我们一起玩耍", "来嘛来嘛", "打死都不去")
jerry_conversation = create_conversation("Jerry", "我不去", "来嘛来嘛")
# 执行对话闭包
tom_conversation("Jerry")
jerry_conversation("Tom")
例二分析:
这段代码定义了一个名为 `create_conversation` 的工厂函数,它用于创建对话闭包。这个工厂函数接收一个参与者的名字(`person_name`)和一系列对话行(`*lines`),然后返回一个新的函数 `conversation`。这个 `conversation` 函数设计用来模拟两个人之间的对话。
让我们逐步分析这段代码:
### **定义工厂函数**
```python
def create_conversation(person_name, *lines):
```
- `create_conversation` 函数接收一个参数 `person_name` 和一个可变参数 `*lines`,后者用于接收任意数量的对话行。
### **定义内部函数**
```python
    def conversation(partner_name):
```
- 在 `create_conversation` 函数内部,定义了一个名为 `conversation` 的内部函数,它接收一个参数 `partner_name`,表示对话的另一方的名字。
### **对话逻辑**
```python
        for i, line in enumerate(lines):
            if i % 2 == 0:
                print(f"{person_name}: {line}")
            else:
                print(f"{partner_name}: {line}")
```
- `conversation` 函数遍历 `lines` 中的所有对话行。
- 使用 `enumerate` 函数获取每个对话行的索引 `i` 和内容 `line`。
- 通过 `if i % 2 == 0` 判断当前行是否为 `person_name` 的发言。
- 根据是奇数行还是偶数行,交替打印两个参与者的发言。
### **返回内部函数**
```python
    return conversation
```
- `create_conversation` 函数返回 `conversation` 函数。这意味着 `conversation` 函数现在是一个闭包,它捕获了 `person_name` 和 `lines` 变量。
### **创建对话闭包**
```python
tom_conversation = create_conversation("Tom", "我们一起玩耍", "来嘛来嘛", "打死都不去")
jerry_conversation = create_conversation("Jerry", "我不去", "来嘛来嘛")
```
- 调用 `create_conversation` 函数创建两个对话闭包:`tom_conversation` 和 `jerry_conversation`。
- 每个闭包都捕获了创建时传入的 `person_name` 和 `lines`。
### **执行对话闭包**
```python
tom_conversation("Jerry")
jerry_conversation("Tom")
```
- 分别调用 `tom_conversation` 和 `jerry_conversation` 函数,模拟两个人之间的对话。
- 传递 `partner_name` 参数给 `conversation` 函数,指定对话的另一方。
### **输出结果**
这段代码将输出以下对话:
```
Tom: 我们一起玩耍
Jerry: 我不去
Tom: 来嘛来嘛
Jerry: 打死都不去
Jerry: 我不去
Tom: 来嘛来嘛
Jerry: 打死都不去
```
- 对话在两个人之间交替进行,展示了闭包如何捕获和使用创建时传入的参数。
### **总结**
这段代码通过使用闭包(closure)机制,创建了两个模拟对话的函数。每个对话函数都捕获了创建时传入的参数,并在函数内部使用这些参数来模拟两个人的对话。这种方法可以有效地模拟具有状态的对话,其中对话的状态由闭包捕获的变量决定。

二、用nonlocal修改闭包内使用的外部变量:

def func_out():
    num1 = 10
    def func_inner():
        nonlocal num1  # 声明 num1 是在外部作用域中定义的
        num1 = 20  # 这将修改外部函数中的 num1 变量
        # 内部要使用外部函数的变量
        result = num1 + 10
        print(result)
    print("修改前的外部变量:", num1)
    func_inner()
    print("修改后的外部变量:", num1)
    return func_inner

new_func = func_out()
new_func()  # 调用返回的 func_inner 函数将被调用

结果:修改前的外部变量: 10
30
修改后的外部变量: 20
30

三、装饰器:

作用:对已有的函数进行额外的功能扩展


http://www.kler.cn/a/592810.html

相关文章:

  • 分治-快速排序系列一>快速排序
  • ESP8266 与 ARM7 接口-LPC2148 创建 Web 服务器以控制 LED
  • 穿越禁区:前端跨域通信的艺术与实践
  • C语言每日一练——day_7
  • Netty基础—6.Netty实现RPC服务二
  • 痉挛性斜颈护理宝典:重拾生活平衡
  • 2025-03-19 学习记录--C/C++-C语言-单链表的结构体定义 + LNode * 和 LinkList 的区别
  • 如何在 HTML 中实现无障碍访问,列举关键措施?
  • NAT及P2P通信
  • 比较常见的几种排序算法
  • 利用knn算法实现手写数字分类
  • Kafka-QA
  • 前端字段名和后端不一致?解锁 JSON 映射的“隐藏规则” !!!
  • 批量删除 PPT 中的所有图片、某张指定图片或者所有二维码图片
  • 链式二叉树概念和结构
  • GPU视频编解码:X86 DeepStream 视频编解码入门(三)
  • PostgreSQL逻辑复制槽功能
  • 华为全流程全要素研发项目管理(81页PPT)(文末有下载方式)
  • 【从零开始学习计算机科学与技术】计算机网络(六)传输层
  • java后端怎么写好根据角色控制查询不同数据,