百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Python 中的Yield和类似概念_python中yield和return的区别

itomcoil 2025-02-17 12:29 33 浏览

Python 充满了强大的功能——其中一个功能就是yield关键字。YIELD常常被忽视,但对于编写高效的代码非常有用。我在处理大型数据集或数据流时使用它。简而言之, yield使程序员能够创建内存高效、响应灵敏的应用程序,这些应用程序可以一项一项地生成项目,而不是一次将所有内容加载到内存中。

让我们探讨一下yield是什么,它是如何工作的,以及它与其他命令(如return的比较。在此过程中,我们将查看现实世界的示例,以帮助您了解何时以及为何使用它。

Python中的yield是什么?

yield关键字用在需要随着时间的推移返回多个值的函数中。与使用return终止并返回单个值的函数不同, yield允许函数根据需要暂停和恢复。这使得yield非常适合您不想一次将所有结果存储在内存中而是一次生成一个结果的情况。

想象一下,您正在编写一个程序来处理一个巨大的文件,例如服务器日志或包含数百万条记录的数据集。将整个文件加载到内存中可能会减慢程序速度,甚至导致程序崩溃。相反,您可以使用yield逐行处理文件。

真实示例:处理大型日志文件

假设您的任务是处理一个 Web 服务器日志文件,该文件记录对网站的每个请求。该文件很大,包含数百万行。您需要解析它,提取相关数据并生成统计数据。一次加载整个文件是不切实际的。使用yield ,您可以逐行处理它,而不会占用过多的内存。

def process_log_file(file_path):
    with open(file_path, 'r') as file:
        for line in file:
            yield line  # Yield one line at a time

for log_line in process_log_file("server.log"):
    analyze_log(log_line)  # Process each line as it is read

在此示例中, process_log_file函数使用yield一次返回一行,然后由analyze_log()处理。这允许您的程序增量地处理文件,从而保持较低的内存使用率和较高的性能。

yield如何运作?

当函数包含yield时,调用它并不会立即执行整个函数。相反,它返回一个可以迭代的生成器对象。每次您向生成器请求下一个项目时,该函数都会从上次停止的位置继续,生成下一个值。

下面是一个简化的示例来展示其工作原理:

def countdown(n):
    while n > 0:
        yield n  # Pause and return n
        n -= 1

# Create a generator
gen = countdown(5)

# Iterating over the generator
for number in gen:
    print(number)

在这种情况下, yield在生成每个数字后暂停countdown()函数。下次调用生成器时,它会从上次停止的地方继续执行。这与使用return不同,在 return 中,函数会立即完成并返回所有内容。

真实示例:API 分页

假设您正在构建一个从远程 API 获取用户数据的应用程序。 API 在页面中提供结果,以避免让客户端感到不知所措。您可以使用yield增量处理每个页面,而不是一次获取所有页面。这样,您的程序仅在需要时处理它需要的内容。

def fetch_data_from_api(api_url, page=1):
    while True:
        response = request_page(api_url, page)
        if not response['data']:
            break
        yield response['data']  # Yield one page of data
        page += 1

for page_data in fetch_data_from_api("https://example.com/api/users"):
    process_page(page_data)  # Process each page as it is retrieved

在此示例中, fetch_data_from_api一次获取一页数据并生成要处理的数据。通过这样做,程序可以保持响应,并且不会浪费内存来预先加载所有数据。

yield与return

乍一看, yield似乎与return类似,但有一些关键的区别。当您使用return时,函数立即终止并发回一个值。使用yield ,函数会暂停,您可以稍后恢复以获取更多值。这使得yield对于处理大型或无限数据流特别有用。

return示例:

def generate_list():
    return [1, 2, 3, 4, 5]

result = generate_list()
print(result)  # Output: [1, 2, 3, 4, 5]

yield示例:

def generate_numbers():
    for i in range(1, 6):
        yield i

gen = generate_numbers()
for number in gen:
    print(number)

使用return ,整个列表在返回之前会在内存中创建。使用yield时,每个数字一次生成一个,从而减少内存占用,尤其是在范围较大的情况下。

现实世界示例:流数据

考虑这样一种情况,您正在处理从传感器连续传输的数据,例如温度读数。传感器不断发送新数据,但您不想收集内存中的所有读数。使用yield ,您可以在每个读数到达时对其进行处理,而无需保存所有读数。

def sensor_data_stream(sensor):
    while True:
        data = sensor.read()
        yield data  # Yield each new sensor reading

for reading in sensor_data_stream(sensor):
    process_reading(reading)  # Process data in real-time

在这种情况下, yield有助于管理持续流入的数据。该程序一次仅处理一个读数,这在处理无限或接近无限的数据流时至关重要

相关推荐

selenium(WEB自动化工具)

定义解释Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7,8,9,10,11),MozillaF...

开发利器丨如何使用ELK设计微服务中的日志收集方案?

【摘要】微服务各个组件的相关实践会涉及到工具,本文将会介绍微服务日常开发的一些利器,这些工具帮助我们构建更加健壮的微服务系统,并帮助排查解决微服务系统中的问题与性能瓶颈等。我们将重点介绍微服务架构中...

高并发系统设计:应对每秒数万QPS的架构策略

当面试官问及"如何应对每秒几万QPS(QueriesPerSecond)"时,大概率是想知道你对高并发系统设计的理解有多少。本文将深入探讨从基础设施到应用层面的解决方案。01、理解...

2025 年每个 JavaScript 开发者都应该了解的功能

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.Iteratorhelpers开发者...

JavaScript Array 对象

Array对象Array对象用于在变量中存储多个值:varcars=["Saab","Volvo","BMW"];第一个数组元素的索引值为0,第二个索引值为1,以此类推。更多有...

Gemini 2.5编程全球霸榜,谷歌重回AI王座,神秘模型曝光,奥特曼迎战

刚刚,Gemini2.5Pro编程登顶,6美元性价比碾压Claude3.7Sonnet。不仅如此,谷歌还暗藏着更强的编程模型Dragontail,这次是要彻底翻盘了。谷歌,彻底打了一场漂亮的翻...

动力节点最新JavaScript教程(高级篇),深入学习JavaScript

JavaScript是一种运行在浏览器中的解释型编程语言,它的解释器被称为JavaScript引擎,是浏览器的一部分,JavaScript广泛用于浏览器客户端编程,通常JavaScript脚本是通过嵌...

一文看懂Kiro,其 Spec工作流秒杀Cursor,可移植至Claude Code

当Cursor的“即兴编程”开始拖累项目质量,AWS新晋IDEKiro以Spec工作流打出“先规范后编码”的系统工程思维:需求-设计-任务三件套一次生成,文档与代码同步落地,复杂项目不...

「晚安·好梦」努力只能及格,拼命才能优秀

欢迎光临,浏览之前点击上面的音乐放松一下心情吧!喜欢的话给小编一个关注呀!Effortscanonlypass,anddesperatelycanbeexcellent.努力只能及格...

JavaScript 中 some 与 every 方法的区别是什么?

大家好,很高兴又见面了,我是姜茶的编程笔记,我们一起学习前端相关领域技术,共同进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力在JavaScript中,Array.protot...

10个高效的Python爬虫框架,你用过几个?

小型爬虫需求,requests库+bs4库就能解决;大型爬虫数据,尤其涉及异步抓取、内容管理及后续扩展等功能时,就需要用到爬虫框架了。下面介绍了10个爬虫框架,大家可以学习使用!1.Scrapysc...

12个高效的Python爬虫框架,你用过几个?

实现爬虫技术的编程环境有很多种,Java、Python、C++等都可以用来爬虫。但很多人选择Python来写爬虫,为什么呢?因为Python确实很适合做爬虫,丰富的第三方库十分强大,简单几行代码便可实...

pip3 install pyspider报错问题解决

运行如下命令报错:>>>pip3installpyspider观察上面的报错问题,需要安装pycurl。是到这个网址:http://www.lfd.uci.edu/~gohlke...

PySpider框架的使用

PysiderPysider是一个国人用Python编写的、带有强大的WebUI的网络爬虫系统,它支持多种数据库、任务监控、项目管理、结果查看、URL去重等强大的功能。安装pip3inst...

「机器学习」神经网络的激活函数、并通过python实现激活函数

神经网络的激活函数、并通过python实现whatis激活函数感知机的网络结构如下:左图中,偏置b没有被画出来,如果要表示出b,可以像右图那样做。用数学式来表示感知机:上面这个数学式子可以被改写:...