Python3 中return和yield的区别
作者:小小程序员ol 发布时间:2023-10-19 09:03:00
一、前言
return一直中,每中语言中其没没有很大差别,就不多说了。(shell语言return的是退出状态,可能差别是比较大的)最早看到yield应该是哪们语言用来调整什么线程优先级的,记不清了,不过那里的yield和python中的yield应该功能有区别。
python中最早看到yield应该是使用scrapy框架写爬虫的时候,之前也有去看yiled的用法,总记不太住。今天又去看了一下,基本上来就是讲些斐波那契数列的烦的要死,自己写段程序研究了一下,这里记一下。
二、return和yield的异同
共同点:return和yield都用来返回值;在一次性地返回所有值场景中return和yield的作用是一样的。
不同点:如果要返回的数据是通过for等循环生成的迭代器类型数据(如列表、元组),return只能在循环外部一次性地返回,yeild则可以在循环内部逐个元素返回。下边我们举例说明这个不同点。
三、实例说明
1 return版本
示例代码如下:
class TestYield:
def gen_iterator(self):
result_list = []
for j in range(3):
print(f"gen_iterator-{j}")
result_list.append(j)
# return在循环的外部,待变量完全生成后一次性返回
return result_list
def call_gen_iterator(self):
# 执行下边这句后result_list直接是完成的结果[0,1,2]
result_list = self.gen_iterator()
for i in result_list:
print(f"call_gen_iterator-{i}")
if __name__ == "__main__":
obj = TestYield()
obj.call_gen_iterator()
执行结果如下,可以看到一次性执行完下层函数,生成完整的迭代器类型返回值result_list,一次性返回给上层函数:
2 yield版本
示例代码如下:
class TestYield:
def gen_iterator(self):
for j in range(3):
print(f"do_something-{j}")
# yield在for循环内部
yield j
def call_gen_iterator(self):
# yield并不是直接返回[0,1,2],执行下边这句后result_list什么值都没有
result_list = self.gen_iterator()
# i每请求一个数据,才会触发gen_iterator生成一个数据
for i in result_list:
print(f"call_gen_iterator-{i}")
if __name__ == "__main__":
obj = TestYield()
obj.call_gen_iterator()
执行结果如下,可以看到上下层函数是交替进行的,即上层函数请求迭代一个值下层函数才生成一个值并立即返回这个值:
3 yield的意义
从上边两个小节可以看到,虽然return和yield两者执行的顺序有区别,但整个要做的事情是一样的,所以使用yield并不会比return快,甚至我们可以猜测由于yield总发生上下文切换在速度上还会慢一些,所以速度不是yield的意义。
他们的主要区别是yiled要迭代到哪个元素那个元素才即时地生成,而return要用一个中间变量result_list保存返回值,当result_list的长度很长且每个组成元素内容很大时将会耗费比较大的内存,此时yield相对return才有优势。
四、yield和return嵌套使用
class TestYield:
def gen_iterator(self):
for j in range(3):
print(f"do_something-{j}")
# yield在for循环内部
yield j
def gen_iterator_middle(self):
print(f"gen_iterator_middle")
# 返回的是迭代器的句柄,所以加一层return不影响是可以理解的
return self.gen_iterator()
def call_gen_iterator(self):
# yield并不是直接返回[0,1,2],执行下边这句后result_list什么值都没有
result_list = self.gen_iterator_middle()
# i每请求一个数据,才会触发gen_iterator生成一个数据
for i in result_list:
print(f"call_gen_iterator-{i}")
if __name__ == "__main__":
obj = TestYield()
obj.call_gen_iterator()
来源:https://www.cnblogs.com/python960410445/p/16348590.html


猜你喜欢
- 一般在更新时会遇到以下场景:1.所有字段全部更新;2.根据条件更新字段中的某部分内容;3.根据不同的条件更新不同的值以下是几种场景中常用的u
- #!/usr/bin/env/ python#coding=utf-8import mechanizeimport cookielib# C
- 介绍set 顾明思义,就是个集合,集合的元素是唯一的,无序的。一个{ }里面放一些元素就构成了一个集合,set里面可以是多种数据类型(但不能
- 我开发过几个采集程序,也研究过很多采集程序代码,所以对采集程序的原理还算是稍微有些了解。先说一下采集原理:采集程序的主要步骤如下: 一、获取
- 1、选取最适用的字段属性MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表
- -------------- 函数检索 --------------trim函数: trim() lTrim() rTrim()校验字符串是
- 问题你想对在Unix系统上面运行的程序设置内存或CPU的使用限制。解决方案resource 模块能同时执行这两个任务。例如,要限制CPU时间
- 选择一个合适的编辑器,比如notepad++、VS、eclipse、sublime text等,选中要集体缩进的代码块,按Tab:集体缩进(
- 1. 简介在 Go 语言中,new 和 make 是用于创建对象的两个内建函数,它们的使用方式和作用有所不同。正确理解 new 和 make
- cv2.getStructuringElement()函数的作用是返回一个结构元素(卷积核),具体解析如下:kernel = cv2.get
- 我使用多进程的一般方式,都是multiprocessing模块中的Pool.map()方法。下面写一个简单的示例和解析。至于此种方法使用多进
- http.ListenAndServetype Server struct { // 请求监听地址 Addr s
- 在默认情况下,大多数浏览器都会将有序列表中的数字序列的与其列表文字内容显示为相同的字体。这篇快速教程将教你如何使用有序列表(ol)和段落(p
- //如果之前有选中的,则把选中radio取消掉$("#tj_cat .pro_category").each(funct
- 引言反射是通过实体对象获取反射对象(Value、Type),然后可以操作相应的方法。在某些情况下,我们可能并不知道变量的具体类型,这时候就可
- 异常的本质导引问题在实际工作中,我们遇到的问题都不是完美的,比如:你写某个模块,用户输入不一定符合你的要求:你的程序要打开某个文件,这个文件
- 什么是事件委托/事件代理利用事件的冒泡传播机制(触发当前元素的某一个行为,它父级所有元素的相关行为都会被触发),如果一个容器中有很多元素都要
- ImageFont模块定义了相同名称的类,即ImageFont类。这个类的实例存储bitmap字体,用于ImageDraw类的text()方
- Django是一个大而全的框架。需要明确的是,传参进行分页获取分页后的数据,一般都是通过向服务器发送get请求的方式实现的,在向后端服务发送
- 环境:python3, 要安 * s4这个第三方库获取请求头的方法这里使用的是Chrome浏览器。打开你想查询的网站,按F12,或者鼠标右键一