Python系列(七):用栗子带你深入了解生成器的send()方法
一.问题引入
在Python中,可以使用生成器来一次返回单个元素,从而可以避免大量占用内存。下面例子中计算房价函数house_price
便是一个生成器的栗子,该函数接收两个参数,其中unit_price
表示每平方米单价,areas
是售卖的房子的面积。
def house_price(unit_price ,areas):for area in areas:yield unit_price * areaunit_price = 1
areas = [100, 120, 110, 180]
for price in house_price(unit_price, areas):print(f"Price: {price}")
"""
Price: 100
Price: 120
Price: 110
Price: 180
"""
但是上述函数无法解决一个问题:在生成器调用的过程中,我们想更改计算房价的每平方米单价。因此我们需要一种方法可以更改生成器每次迭代的unit_price
参数值,这个需求可以做到吗?但是的肯定可以。生成器的send()
方法就可以解决这个问题。
二.send()方法详细介绍
生成器的send()
方法可以往生成器发送一个值并返回生成器生成的下一个值,下面举个简单的栗子来简单介绍下该方法。
def my_generator():receive = yield 3yield f"{receive}"myg = my_generator()
print(myg.send(None)) # print(next(myg))与其作用是等同的
# 3
print(myg.send(5))
# 5
首先,解释下receive = yield 3
这行代码,这行代码可以拆成两部分来看,即yield 3
和receive = yield
,前者表示生成一个新的值,后者指接收send()
方法传过来的值。在执行顺序上,调用send()
方法后会先yield 3
,当再次调用next()
方法时才会完成receive
的赋值。
send()方法会引发一次
next()
方法的调用。
然后,再解释下为啥需要myg.send(None)
,这是send()
方法的低层实现硬性规定的,当首次执行时不允许带有参数,下面的对应该部分的低层源码:
if (f->f_lasti == -1) { // f_lasti==-1 代表首次执行if (arg && arg != Py_None) { // 首次执行不允许带有参数PyErr_SetString(PyExc_TypeError,"can't send non-None value to a ""just-started generator");return NULL;}
}
在上述栗子中,若去掉myg.send(None)
,则会报错:TypeError: can't send non-None value to a just-started generator
。
三.问题解决
有了send()
方法,我们现在给出第一节中问题的解决方案:
def house_price(areas):unit_price = yield # 接收初始的unit_pricefor area in areas:unit_price = yield unit_price * areaunit_prices = [1, 2, 3, 1]
areas = [100, 120, 110, 180]
hp = house_price(areas)
hp.send(None) # 启动生成器
for unit_price in unit_prices:cur_price = hp.send(unit_price)print(f"Price: {cur_price}")
"""
Price: 100
Price: 240
Price: 330
Price: 180
"""
可以看到通过send()
方法,我们可以为每个交易指定一个房价。
结语
从前面的介绍可以看出:send()
方法提供了调用者与生成器间的通信机制,通过该机制我们可以进行一些特殊操作,当然这也要视需求而定。
参考资料:
- Python Generator 生成器的send方法到底有啥用?
- 为什么python的yield第一次不能用send发送数据?
以上便是本文的全部内容,要是觉得不错的话,可以点个赞或关注一下博主,你们的支持是博主创作的不竭动力,当然要是有问题的话也敬请批评指正!!!
Python系列(七):用栗子带你深入了解生成器的send()方法相关推荐
- Python生成器的send方法、递推函数、匿名函数及常用内置函数
1.生成器的send方法 在使用yield方法创建生成器时,不仅可以使用next方法进行取值,还可以通过send方法向生成器的内部传值 1.1 什么是send方法? send方法相当于高级的next方 ...
- python 生成器 send_python(可迭代对象,迭代器,生成器及send方法详解)
一.可迭代对象 对象必须提供一个__iter__()方法,如果有,那么就是可迭代对象, 像列表,元祖,字典等都是可迭代对象 可使用isinstance(obj,Iterable)方法判断 1 from ...
- Python生成器对象send()方法用法
关于生成器基本用法请参考详解Python生成器函数和生成器对象的原理和用法 >>> def f(): yield from 'abcdefg' #使用yield表达式 ...
- python第七关再来一盘_7、 Python系列,七,的,集合
集合 1.什么是集合 我们可以把集合看作是没有存储value的字典,也就是说可以把集合看作是只有key的字典. 我们知道字典中的key它必须是不可变的类型,因为我们要根据key调用哈希函数hash() ...
- python 廖雪峰_廖雪峰的Python系列教程(20)——高级特性之生成器
生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大 ...
- python生成器的send方法
官方文档: generator.send(value) 恢复执行并向生成器函数"发送"一个值. value 参数将成为当前 yield 表达式的结果. send() 方法会返回生成 ...
- Python 高级编程和异步IO并发编程 --12_7 生成器进阶- yield from
# Python 3.3新加了yield from语法 from itertools import chain # chain可以将迭代的类型给连接起来,直接做一个for循环 my_list = [1 ...
- 带你自学Python系列(七):Python列表复制陷阱
↑ 点击上方[计算机视觉联盟]关注我们 今天是小编持续更新关于Python的知识总结以及Python实践项目应用的第7天,带你利用零碎时间自学最受欢迎的编程语言之一Python语言.你和小编一起打卡了 ...
- 带你自学Python系列(八):列表具体操作思维导图总结,再也不用翻书查用法了!...
↑ 点击上方[计算机视觉联盟]关注我们 今天是小编持续更新关于Python的知识总结以及Python实践项目应用的第8天,带你利用零碎时间自学最受欢迎的编程语言之一Python语言.你和小编一起打卡了 ...
最新文章
- SHELL判断服务是不是正在运行
- python散点图拟合曲线-使用python通过点拟合曲线
- python谷歌浏览器驱动安装失败_阿里云centos7.2下安装chrome浏览器+webdriver+selenium及常见设置-傻瓜教程...
- MongoDB 基础教程CURD帮助类
- GDCM:gdcm::StreamImageWriter的测试程序
- 不要轻易修改ESX主机的主机名
- Linux下遍历目录下的文件
- Namomo Spring Camp Div2 Week1 - 第四次打卡
- c语言提高,C语言提高-day2
- 终于有人把Docker讲清楚了
- 谷歌停止华为合作;联想声明未向华为断供;Android 遭反垄断调查 | 极客头条...
- 精选|2018年8月R新包推荐
- manjaro linux vmware,Manjaro Linux处理vmware的vmmon、vmnet8、Network configuration is missing一堆问题的记录...
- 技术管理 - 思维导图(补)
- Google SketchUp Cookbook: (Chapter 4) Advanced Intersect and Follow Me Techniques
- 第一章:计算机组成与体系结构(软件设计师备考)
- 青岛科技大学计算机硕士就业,2021年青岛科技大学专业排行榜,哪个专业就业比较好...
- ElasticKibana 安装部署
- Android 10.0获取本地视频及其预览图
- 日程定时提醒程序C语言,DIY一个高大上带提醒的计时器,简单实用,你还在等什么...