展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > Yield关键字作用与生成器流程解析

Yield关键字作用与生成器流程解析

yield关键字使函数变为生成器,实现暂停执行、按需返回值并保存状态,相比列表更节省内存,适用于处理大数据、惰性计算和无限序列,yieldfrom则简化了子生成器委托,提升代码简洁性与可维护性。

本文目录

    yield关键字使函数变为生成器,实现暂停执行、按需返回值并保存状态,相比列表更节省内存,适用于处理大数据、惰性计算和无限序列,yield from则简化了子生成器委托,提升代码简洁性与可维护性。

    yield 关键字的作用与生成器工作流程

    yield 关键字在 Python 中扮演着一个非常独特的角色,它能将一个普通函数“转化”为生成器(generator)。简单来说,当你在一个函数中使用 yield 语句时,这个函数就不会立即执行完并返回一个单一结果,而是变成一个迭代器,每次被请求时才“暂停”执行并“吐出”一个值,然后记住它当前的所有状态,等待下一次被唤醒时从上次暂停的地方继续执行。这对于处理大量数据或构建惰性计算序列来说,是极其高效且优雅的解决方案。

    yield 关键字的作用与生成器工作流程

    在我看来,yield 关键字是 Python 语言中一个非常精妙的设计,它彻底改变了函数的工作模式。一个包含 yield 的函数,当你调用它时,它并不会像普通函数那样直接运行函数体内的代码,而是返回一个特殊的迭代器对象,也就是我们常说的“生成器对象”。

    这个生成器对象才是真正的工作者。当你对它调用 next() 方法(或者在 for 循环中迭代它)时,函数体内的代码才会开始执行,直到遇到第一个 yield 语句。此时,函数会“暂停”执行,将 yield 后面的值作为结果返回。更关键的是,它会把当前函数的所有局部变量和执行状态都保存下来。

    当生成器对象再次被请求下一个值时(再次调用 next()),函数会从上次暂停的地方,也就是上次 yield 语句之后的那一行,继续执行。这个过程会一直重复,直到函数体执行完毕,或者遇到 return 语句(此时生成器会抛出 StopIteration 异常,表示没有更多的值了)。

    这种“按需生成”的模式,与传统的“一次性生成所有结果并存储”的模式形成了鲜明对比。它最直接的好处就是极大地节省内存。想象一下,如果你需要处理一个亿万级别的数据序列,把它全部加载到内存中几乎是不可能的。但如果用生成器,我们每次只需要处理一个数据项,内存占用就能保持在一个非常低的水平。

    def simple_generator():
        print("开始生成...")
        yield 1
        print("生成了1,继续...")
        yield 2
        print("生成了2,快结束了...")
        yield 3
        print("生成完毕。")
    
    # 调用函数,得到的是一个生成器对象
    gen = simple_generator()
    
    # 每次调用next(),函数才执行一部分
    print(next(gen)) # 输出:开始生成... 1
    print(next(gen)) # 输出:生成了1,继续... 2
    print(next(gen)) # 输出:生成了2,快结束了... 3
    
    # 再次调用会抛出StopIteration
    # print(next(gen)) # 输出:生成了3,快结束了... 生成完毕。 StopIteration

    你看,这个例子清晰地展示了 yield 如何控制函数的执行流。每次 next() 都像给生成器“打了一针兴奋剂”,让它向前走一步,吐出一个值,然后再次“冬眠”。

    生成器与普通函数有何本质区别?为何选择生成器而非列表?

    这问题问到了点子上,也是很多初学者容易混淆的地方。在我看来,生成器和普通函数最根本的区别在于它们的执行模型和内存管理策略。

    普通函数是“一次性”的。当你调用一个普通函数时,它会从头到尾执行完毕,然后返回一个(或零个)结果。函数执行过程中产生的任何局部变量,在函数返回后就都“烟消云散”了。它就像一个短跑运动员,冲刺到底,然后休息。

    而生成器函数则更像一个“马拉松运动员”,它会跑一段,停下来喘口气(yield),把当前跑到哪儿了、身体状态如何都记下来,然后把阶段性成果(yield 的值)给你。等你下次需要时,它再从上次停下的地方接着跑。这种“暂停-恢复”的机制,使得生成器能够保存其内部状态,这是普通函数做不到的。

    至于为什么选择生成器而非列表,核心考量就是效率和资源消耗。

    1. 内存效率: 这是生成器最大的优势。列表(list)会一次性将所有元素加载到内存中。如果你的数据量非常大,比如一个GB级别的日志文件,或者一个理论上无限的数字序列,将它们全部存入列表会直接导致内存溢出。生成器则不然,它每次只在需要时生成一个元素,内存中只保存当前生成状态和少量数据,极大地降低了内存占用。
    2. 惰性计算(Lazy Evaluation): 生成器是惰性求值的典范。它只计算你真正需要的部分。比如,你可能只需要一个序列的前100个元素,即使这个序列可以无限长,生成器也只会计算到第100个就停止。而如果你用列表来表示,即使你只取前100个,也可能需要先计算出所有元素。这在处理大型数据集或网络流时尤其重要。
    3. 无限序列: 只有生成器才能优雅地表示无限序列,比如斐波那契数列、质数序列等。因为它们不需要一次性生成所有元素,而是按需提供。

    所以,如果你的数据量可控,或者你需要频繁地随机访问列表中的元素,那么列表可能是更好的选择。但如果你的数据量巨大、需要进行流式处理,或者希望实现惰性计算,那么生成器无疑是更明智、更高效的选择。

    如何理解yield from的用法及其优势?

    yield from 是 Python 3.3 引入的一个语法糖,它主要是为了简化委托给子生成器的逻辑。初看可能有点迷惑,但一旦理解了它的应用场景,你会发现它让代码变得非常简洁和强大。

    想象一下,你有一个复杂的生成器,它需要从多个不同的“源”生成数据。在 yield from 出现之前,你可能会写出这样的代码:

    def sub_generator_a():
        yield 'A1'
        yield 'A2'
    
    def sub_generator_b():
        yield 'B1'
        yield 'B2'
    
    def main_generator_old():
        for item in sub_generator_a():
            yield item
        for item in sub_generator_b():
            yield item
    
    # 使用旧方法
    for x in main_generator_old():
        print(x)
    # 输出:A1 A2 B1 B2

    这段代码虽然能工作,但 for item in ... yield item 这种模式写多了会显得有些冗余。yield from 就是来解决这个问题的。它允许一个生成器直接将迭代的控制权委托给另一个迭代器(通常是另一个生成器)。

    使用 yield from 后,代码会变得更简洁:

    def sub_generator_a():
        yield 'A1'
        yield 'A2'
    
    def sub_generator_b():
        yield 'B1'
        yield 'B2'
    
    def main_generator_new():
        yield from sub_generator_a() # 委托给sub_generator_a
        yield from sub_generator_b() # 委托给sub_generator_b
    
    # 使用新方法
    for x in main_generator_new():
        print(x)
    # 输出:A1 A2 B1 B2

    这看起来只是简化了代码,但 yield from 的能力远不止于此。它不仅仅是语法糖,更重要的是,它能够透明地处理子生成器的所有通信,包括 send()、throw() 和 close() 方法。这意味着外部调用者可以直接与子生成器进行交互,而不需要主生成器做额外的转发处理。这在构建更复杂的协程(coroutines)和异步编程模式时,显得尤为重要,因为它允许数据和控制流在多层生成器之间无缝传递。

    简而言之,yield from 的优势在于:

    1. 代码更简洁: 避免了冗余的 for item in ... yield item 模式。
    2. 更强大的委托: 不仅传递 yield 的值,还能处理 send()、throw() 等方法,使得子生成器能够接收外部输入或处理异常。
    3. 构建复杂生成器链: 使得多个生成器可以像乐高积木一样组合起来,形成一个更强大的数据处理管道。

    生成器在实际开发中常见的应用场景有哪些?

    生成器在实际开发中简直是无处不在,尤其是在需要处理大量数据或构建高效数据流的场景。我个人在很多项目中都依赖它来优化性能和内存。

    1. 处理大型文件: 这是最经典的场景之一。比如,你需要读取一个几十GB的日志文件或CSV文件。如果一次性 readlines(),内存肯定吃不消。使用生成器可以逐行读取,每次只在内存中保留一行数据进行处理。

      def read_large_file(filepath):
          with open(filepath, 'r', encoding='utf-8') as f:
              for line in f:
                  yield line.strip()
      
      # 逐行处理文件,而不会一次性加载所有内容
      for log_entry in read_large_file('my_huge_log.txt'):
          if "ERROR" in log_entry:
              print(f"发现错误:{log_entry}")
    2. 数据流处理管道: 当你需要对数据进行一系列的转换、过滤操作时,生成器可以构建一个高效的“数据处理管道”。每个生成器负责一个步骤,将处理后的结果 yield 给下一个生成器。

      def filter_even(numbers):
          for n in numbers:
              if n % 2 == 0:
                  yield n
      
      def square(numbers):
          for n in numbers:
              yield n * n
      
      # 构建管道:生成数字 -> 过滤偶数 -> 求平方
      nums = range(1, 11)
      processed_data = square(filter_even(nums)) # 惰性求值
      
      for res in processed_data:
          print(res) # 输出:4 16 36 64 100

      这种链式调用,每个步骤都是惰性的,只有在真正需要结果时才计算。

    3. 实现自定义迭代器: 如果你需要一个自定义的数据结构,或者希望以非传统方式遍历一个对象,生成器提供了一种非常简洁的方式来实现 __iter__ 方法,让你的对象变得可迭代。

    4. 无限序列的生成: 像斐波那契数列、质数生成器等,它们本质上是无限的。生成器是唯一能在不耗尽内存的情况下表示和使用这些序列的方式。

      def fibonacci_sequence():
          a, b = 0, 1
          while True:
              yield a
              a, b = b, a + b
      
      fib_gen = fibonacci_sequence()
      for _ in range(10):
          print(next(fib_gen)) # 输出前10个斐波那契数
    5. 资源管理(配合 contextlib.contextmanager): 虽然不是直接使用 yield,但 contextlib.contextmanager 装饰器就是基于生成器实现的,它提供了一种简洁的方式来创建上下文管理器,确保资源的正确获取和释放(比如文件句柄、数据库连接等)。

    这些场景都体现了生成器在提高代码效率、降低内存消耗和增强代码可读性方面的巨大价值。掌握了 yield,你就掌握了 Python 中处理大规模数据和构建高效数据流的利器。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。