- 生成器


我们调用一个普通的Python函数时,一般是从函数的第一行代码开始执行,结束于return语句、异常或者函数结束(可以看作隐式的返回None)。一旦函数将控制权交还给调用者,就意味着全部结束。函数中做的所有工作以及保存在局部变量中的数据都将丢失。再次调用这个函数时,一切都将从头创建。 
对于在计算机编程中所讨论的函数,这是很标准的流程。这样的函数只能返回一个值,不过,有时可以创建能产生一个序列的函数还是有帮助的。要做到这一点,这种函数需要能够“保存自己的工作”。 
我说过,能够“产生一个序列”是因为我们的函数并没有像通常意义那样返回。return隐含的意思是函数正将执行代码的控制权返回给函数被调用的地方。而"yield"的隐含意思是控制权的转移是临时和自愿的,我们的函数将来还会收回控制权。

最初的引入是为了让程序员可以更简单的编写用来产生值的序列的代码

▲.生成值的序列

处理无限序列==>占用内存太大==>遇到问题:函数只有一次返回结果的机会,因而必须一次返回所有的结果==>如果get_primes可以只是简单返回下一个值,而不是一次返回全部的值

一个生成器函数的定义很像一个普通的函数,除了当它要生成一个值的时候,使用yield关键字而不是return。如果一个def的主体包含yield,这个函数会自动变成一个生成器(即使它包含一个return)。除了以上内容,创建一个生成器没有什么多余步骤了。

△生成器就是一类特殊的迭代器。作为一个迭代器,生成器必须要定义一些方法(method),其中一个就是next()。如同迭代器一样,我们可以使用next()函数来获取下一个值。

while循环是用来确保生成器函数永远也不会执行到函数末尾的

PEP 342加入了新的特性

通过send方法来将一个值”发送“给生成器。other = yield foo 这样的语句的意思是,"返回foo的值,这个值返回给调用者的同时,将other的值也设置为那个值

    def get_primes(number):while True:if is_prime(number):number = yield numbernumber += 1通过这种方式,我们可以在每次执行yield的时候为number设置不同的值。现在我们可以补齐print_successive_primes中缺少的那部分代码:def print_successive_primes(iterations, base=10):prime_generator = get_primes(base)prime_generator.send(None)for power in range(iterations):print(prime_generator.send(base ** power))

- 理解send

    def Get_allprimes(num):while True:if prime_num(num):print('num',num)other = yield numprint('other',other)num += 1gene = Get_allprimes(34)gene.send(None)gene.send(61)output:>>>num 37>>>other 61>>>num 41

★ 重点:看这句xx = yield yy

摘要:send()的作用是使xx赋值为发送的值(send的参数),然后让生成器执行到下个yield..

使用send(params)需要区分情况。△注意:如果生成器未启动,则必须在使用send()前必须要启动生成器,而启动的方法可以是generator.next()或是generator.send(None)执行到第一个yield处.之后就可以使用send(params)不断传入值了。如果是已启动,则send(params)的作用就是给xx赋值为发送的值(send的参数),然后让生成器执行到下个yield..

为什么需要send(None),也很好理解,因为 生成器还没有走到第一个yield语句,如果我们发生一个真实的值,这时是没有人去“接收”它的。一旦生成器启动了,就对象接受(即=号左边的左值xx接受了),之后就可以使用send(params)不断传入值了

▲注意,每次的send()都会运行到yield语句,但赋值不会执行,只会有返回值,相当于return后就退出函数了,所以在返回值之后的赋值就不会执行了。

在我看来send()的作用是在next()的基础上,多了个给xx赋值的功能。如第二次的gene.send(61)先从上次停住的yield处开始运行,使other 赋值为61,然后执行到下一个yield处===>可以看出当send方法的参数为None时,它与next方法完全等价

More(给还未懂的人更详细的讲解):
  • send(None)启动后send(int类参数),然后再传个send(None)效果是怎样的?
    def Gene():         #生成器函数print("ok")x = 100         print(x)first = yield 50    #这里就是send函数的关键# send所传递的值其实就是给 =号左边的左值赋值print(first)second = yield x  # 这里试第二个断点print(second)z = 'third'third = yield zprint(third)inst = Gene()                   #创建生成器对象output1 = inst.send(None)       #启动生成器,运行到第一个yieldprint(output1)                 #这边的output1获得的是yield的返回值 50output2 = inst.send(30)print(output2)output3 = inst.send(None)output:>>>ok>>>100      ==>print(x)>>>50       ==>print(output1)>>>30       ==>send(30)后first被赋值为30然后print(first)>>>100      ==>print(output2) ==>output = x==100>>>None     ==>send(None)second被赋值为None,print(second)==>None
每次的send(params)都会运行到yield语句,但赋值不会执行,只会有返回值。赋值在下一次send(params)时将xx赋值为params,执行过程如下

只有返回值:

output1接受返回值:


执行send(params):

将passvalue赋值为params:

接受运行到的第二个yield的返回值:

参考博客生成器

转载于:https://www.cnblogs.com/nymrli/p/9416949.html

Python生成器及send用法讲解相关推荐

  1. Python生成器对象send()方法用法

    关于生成器基本用法请参考详解Python生成器函数和生成器对象的原理和用法 >>> def f():     yield from 'abcdefg'     #使用yield表达式 ...

  2. Python生成器(send,close,throw)方法详解

    <Python生成器>一节中,详细介绍了如何创建一个生成器,以及生成器的基础用法.本节将在其基础上,继续讲解和生成器有关的一些方法. Python生成器send()方法 我们知道,通过调用 ...

  3. Python生成器的send方法、递推函数、匿名函数及常用内置函数

    1.生成器的send方法 在使用yield方法创建生成器时,不仅可以使用next方法进行取值,还可以通过send方法向生成器的内部传值 1.1 什么是send方法? send方法相当于高级的next方 ...

  4. python生成器的send方法

    官方文档: generator.send(value) 恢复执行并向生成器函数"发送"一个值. value 参数将成为当前 yield 表达式的结果. send() 方法会返回生成 ...

  5. python生成器方法send的使用

    def f():a,b=1,1while True:v=(yield a)if v:a=va,b=b,a+b a=f() for i in range(5):print(a.__next__()) p ...

  6. 理解Python生成器的send函数

  7. Python生成器next方法和send方法区别详解

    yield的语法规则是: 在yield这里暂停函数执行,并返回yield后面表达式的值(默认为None),直到被next()再次调用时,从上次暂停的yield代码处继续往下执行.当没有可继续next( ...

  8. python中append函数什么意思_python中append函数用法讲解

    python中append函数用法讲解 如果在做一个地区的统计工作,可以使用列表来帮助我们.输入汉字或者其他字符,比如"01代表汉族",那么在写民族的时候有下拉列表,就可以打01, ...

  9. python中yield的用法(生成器的讲解)

    2 理解说明yield与生成器 在Python中,使用yield的函数被称为生成器函数(generator function). 生成器有两种方法:next()和send(),都可以调用生成器 yie ...

最新文章

  1. iis6如何升级iis7_IIS修复IIS出现错误后如何完全卸载重装
  2. java基础----数据结构与算法----Java API:集合 以及 排序相关API
  3. java 网线串口开发_C++标准语言不断被开发,C++却走向了下坡路!
  4. python创建学生类和教师类_创建StudentServices类
  5. linux tar命令 打包 解压
  6. RequestDispatcher提供两个方法:forward,include有什么区别
  7. 两篇 Spring 总结(一)
  8. 唐山大地震 昨夜万人首映 尚雯婕演唱《23秒,32年》使观众情绪得以第二次温暖爆发...
  9. WPA2 Key Reinstallation 漏洞
  10. K-periodic Garland
  11. Maven原始setting.xml文件备份
  12. css3 中的calc用法
  13. LAMP源码环境搭建
  14. SqlServer误删数据恢复
  15. Kotlin 开发Android app(十九):文件读写和SharedPreferences内容存储
  16. bboss ioc快速入门教程
  17. go 及GoLand 环境安装
  18. 经济增长(二)索洛模型
  19. Presto(4)presto客户端查询保存成文件
  20. C++ 算法设计与分析 地图着色问题(中国+美国)

热门文章

  1. 目标检测中的mAP是什么含义?
  2. ImageNet数据集下载及整理
  3. 081200计算机科学与技术专业,研究生计算机科学与技术专业排名
  4. windows7经典开机音乐_糖豆人加入索尼克皮肤;三国群英传8上线Steam;疑似PS5开机音效...
  5. SPU、SKU、ID,它们都是什么意思,三者又有什么区别和联系呢?
  6. c 数组上限_深度文章,高手必看:C编程表驱动法编程实践(精华帖,建议收藏并实践)...
  7. .Net下的分库分表帮助类——用分库的思想来分表 - 秋夜 - 博客园
  8. 栈练习之Example005-检查一个程序中的花括号、方括号和圆括号是否配对
  9. mysql 6安装当前密码_windows安装mysql数据库并修改密码
  10. 一句话获取spring下所有注解