yield

# -*- coding: utf-8 -*-
def g(x):
    while True:
       ret = yield 1

       print('ret = ', ret)

# print(g(5))
# print(g(5))
# print(g(5)==g(5))
# <generator object g at 0x108da9830>
# <generator object g at 0x108da9830>
# False

看到了吗?两次调用不是同一对象,所以下面这样执行会报错:
# print(g(5).send(None))# 0 相当于调用了一次next?
# print(g(5).send())
# 打印 :
# 报错
# 0
# 因为g(5) 和 g(5)不是同一个对象了 ,而调用send()之前必需send(None)

正确做法:
f = g(5)
print('send None ', f.send(None)) #1 就是说yield后面的值给了函数调用者 第一次send相当于启动生成器 
print('send None 第二次 = ' , f.send(None)) # 调用此处时 从yield后面的语句执行 当send括号中有值 yield返回不再是1 而是括号中的值 但是括号中不能什么都没有 否则会报错。就是说函数调用的结果是yield的返回值 ,而ret的值是send括号中发送的值。就这么理解就行了。
print('send 222 = ' , f.send(222))
# 打印 :
send None 1
ret = None
send None 第二次 = 1
ret = 222
send 222 = 1



结论:
yield不仅可以像return一样返回值,也可以接收值
但是调用生成器send方法传递数据时,必须先调用next(c)或者c.send(None)方法,执行到yield语句,等待接收数据。否则会报错

 

yeild 与 yeild from 去参考 https://blog.csdn.net/chenbin520/article/details/78111399?locationNum=7&fps=1

 

#说明:yield from iterable本质上等于
for item in iterable:
    yield item
的缩写版

http://blog.csdn.net/u010161379/article/details/51645264

生成器是一种特殊的函数,运行期间不会返回值,而是包进一个囊中,程序会挂起,待结束运行可以对囊调用next(),遍历囊中的值。

对一个生成器对象调用send方法,(传入send()的参数为None  或者 有效值)结果是: 


为什么python的yield第一次不能用send发送数据?

这个 python 手册里面就有写吧。python 的 generator 初始化时还没有被运行。所以你直接用 a = G() 不能达到你想要的效果,要在 a=G() 后面加一句 a.next() 才开始运行了。开始运行之后才能 send()。

send函数实质上与next()是相似的,区别是send是传递yield表达式的值进去,而next不能传递特定的值,只能传递None进去,因此可以认为g.next()和g.send(None)是相同的。

简单地讲,yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield

 

https://blog.csdn.net/libbyandhelen/article/details/78957369 主要介绍为什么使用yield ,主要是节约内存。

 

说的通俗易懂:https://blog.csdn.net/iPenX/article/details/78310476 它主要分析了 有yield的代码程序走的步骤。

posted @ 2017-08-12 09:35  liuw_flexi  阅读(175)  评论(0编辑  收藏  举报