notes notes
首页
  • 主题初衷与诞生
  • 介绍
  • 快速上手
  • 目录结构
  • 相关文章

    • 使目录栏支持h2~h6标题
    • 如何让你的笔记更有表现力
    • 批量操作front matter工具
    • 部署
    • 关于写文章和H1标题
    • 关于博客搭建与管理
  • PostgreSQL 全文搜索
  • 依赖注入
  • 开发常见问题
  • 逻辑删除
  • TCP 粘包和拆包
  • netty 粘包和拆包
  • 在k8s集群中搭建一个harbor私有仓库
  • 优雅停机
  • helm 命令学习
  • yield 关键字
  • 不定参数
TODO
  • REST API
  • 使用 IntelliJ IDEA 反编译 jar
  • Spring Boot 删除前后空白字符
  • 设计模式

    • 装饰器模式
Docker
Tool Box (opens new window)
GitHub (opens new window)
首页
  • 主题初衷与诞生
  • 介绍
  • 快速上手
  • 目录结构
  • 相关文章

    • 使目录栏支持h2~h6标题
    • 如何让你的笔记更有表现力
    • 批量操作front matter工具
    • 部署
    • 关于写文章和H1标题
    • 关于博客搭建与管理
  • PostgreSQL 全文搜索
  • 依赖注入
  • 开发常见问题
  • 逻辑删除
  • TCP 粘包和拆包
  • netty 粘包和拆包
  • 在k8s集群中搭建一个harbor私有仓库
  • 优雅停机
  • helm 命令学习
  • yield 关键字
  • 不定参数
TODO
  • REST API
  • 使用 IntelliJ IDEA 反编译 jar
  • Spring Boot 删除前后空白字符
  • 设计模式

    • 装饰器模式
Docker
Tool Box (opens new window)
GitHub (opens new window)
  • yield 关键字
    • 不定参数
    目录

    yield 关键字

    yield 关键字只能出现在函数体中,它用于将函数转变成一个生成器。

    当需要从生成器中取值时,程序会执行到 yield 关键字出现的位置,将 yield 返回给调用方,并暂停生成器函数的执行;当下次再从生成器中取值时,从上次暂停的地方继续执行。

    因此,yield 实际上提供了一个 lazy 的序列,其值是在调用方真正获取值时才生成的。它无需预先将整个序列加载到内存中,在遍历大序列时可以明显节约内存资源。

    # 基本用法

    # 取值

    使用 yield 定义一个生成器,并从中取值:

    def generate_value():
        print('generator staring...')
        yield 1
        print('generator ending...')
    
    # 调用包含 yield 关键字的函数,会得到生成器    
    generator = generate_value()
    # 首次从生成器中取值,取值后生成器将暂停执行
    print('first value: %s' % (next(generator)))
    print('now, start to get second value...')
    # 第二次从生成器中取值,将从上次暂停的点继续执行
    # 由于生成器中已经没有多余元素,此时会抛出StopIteration
    print('second value: %s' % (next(generator)))
    

    执行输出为:

    generator staring...
    first value: 1
    now, start to get second value...
    generator ending...
    Traceback (most recent call last):
      File "a.py", line 10, in <module>
        print('second value: %s' % (next(generator)))
    StopIteration
    

    # 遍历

    • 可以使用 for循环 遍历 yield 生成器
    • 可以使用 yield 生成器构建 list 等容器
    # 一个函数中可以出现多个 yield 关键字,每取一次值就执行到一个 yield。
    def generate_value_1():
        yield 1
        yield 2
    
    def generate_value_2(num):
        cnt = 0
        while cnt < num:
            yield cnt
            cnt += 1
        
    generator_1 = generate_value_1()
    
    print('iterator generator...')
    for i in generator_1:
        print(i)
    
    print('get list from generator: %s' % (list(generate_value_2(3))))
    

    输出为:

    iterator generator...
    1
    2
    get list from generator: [0, 1, 2]
    

    # 与 return 共存

    yield 关键字可以和 return 关键字共存在一个函数体内。当执行到 return 语句时,退出函数。

    # 定义一个生成器,最多只能生成 max 个元素
    def generator_value(num, max=5):
        cnt = 0
        while cnt < num:
            if cnt == max:
                return
            else:
                yield cnt
                cnt += 1
    
    print(list(generator_value(10)))
    

    输出为:

    [0, 1, 2, 3, 4]
    

    # 高级用法

    yield 生成器对象具有一个特殊的方法叫做 send(),它可以用于在生成器的暂停状态下发送值,并作为 yield 表达式的结果。这种双向通信的能力可以用于在生成器与外部环境之间进行数据交换和协调。

    # 基本用例

    def generate_value():
        # 生成器首次执行时,到此处暂停,等待接受 send() 传递的值
        # 接受成功后,将接收到的值赋给等号左边的变量,并继续向下执行
        value = yield 
        # 将计算结果返回调用方
        yield value + 1
    
    generator = generate_value()
    
    # 启动生成器
    next(generator) # 首次通过 next() 或者 send(None) 以启动生成器
    
    # 使用 send() 发送数据并获取结果
    print(generator.send(10)) 
    

    输出为:

    11
    

    生成器和外部环境可以双向通信,可用于一些高级功能的实现,如:

    • 控制生成器的执行流程
    • 实现协程和状态机

    # 控制生成器的执行流程

    如下示例中,可以通过外部变量控制生成器内部计数器的增减:

    def counter():
        i = 0
        while True:
            command = yield i # 返回 i 的值,并在此处等待 send() 发送的值,一旦接受到,将其赋给 command,并继续执行 
            if command == 'increment':
                i += 1
            elif command == 'decrement':
                i -= 1
    
    # 创建生成器对象
    gen = counter()
    
    # 启动生成器,执行到第一个 yield
    next(gen)
    
    # 控制生成器的执行流程
    print(gen.send('increment'))  # 输出:1
    print(gen.send('increment'))  # 输出:2
    print(gen.send('decrement'))  # 输出:1
    

    # 实现状态机

    如下示例中,模拟一个简单的状态机,根据当前的状态和接收到的事件进行状态转换。通过发送不同的事件,可以控制状态机在不同的状态之间切换。

    def state_machine():
        state = 'INIT'
        while True:
            event = yield state
            if state == 'INIT':
                if event == 'start':
                    state = 'RUNNING'
            elif state == 'RUNNING':
                if event == 'stop':
                    state = 'STOPPED'
            elif state == 'STOPPED':
                if event == 'reset':
                    state = 'INIT'
    
    # 创建生成器对象
    sm = state_machine()
    
    # 启动生成器,执行到第一个 yield
    next(sm)
    
    # 控制状态机的状态转换
    print(sm.send('start'))   # 输出:'RUNNING'
    print(sm.send('stop'))    # 输出:'STOPPED'
    print(sm.send('reset'))   # 输出:'INIT'
    
    上次更新: 2023/12/08, 06:34:37
    不定参数

    不定参数→

    Theme by Vdoing | Copyright © 2023-2023
    Powered by vuepress-theme-vdoing
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式