yield
yield,可以看为return,但是返回的不是一个函数的输出,是一个生成器的结果。当程序遇到yield后,停止执行并返回,当再次调用时,会在停止的地方继续执行。一个方法用来yield,那么它就是一个生成器。
注意:
- 必须要启动一次next(func),才能seed非空值,否则只能seed(None)
- seed(None),相当于next(func)
举例1:
```python def fun(): print(“函数开始”) while True:
run = fun() print(next(run)) print(“———————————“) print(next(run)) ‘’’ 函数开始 1result = yield 1
print("result:{}".format(result))
result:None 1 ‘’’ ‘’’ 流程: 1.run = fun(),得到生成器run 2.调用next方法,fun函数开始执行,先print方法,然后进入while循环 3.遇到yield,然后把yield想成return,return了一个1之后,程序停止,需要注意:此时并没有执行赋值给result操作 4.执行print(“———————————“) 5.再次调用next方法,此时从上次停止的地方执行,也就是给result赋值,但是由于右边已经return出去了,同时也没传参数, 所以result是空的(None) 6.print(“result:{}”.format(result)) 7.进入while True,遇到yield,也就是return了一个1之后,程序停止。 ‘’’
<a name="tFz9p"></a>
### 举例2:
```python
def fun():
print("函数开始")
while True:
result = yield 1
print("result:{}".format(result))
run = fun()
print(next(run))
print("----------------------")
print(run.send(2))
'''
函数开始
1
----------------------
result:2
1
'''
'''
流程:
1.run = fun(),得到生成器run
2.调用next方法,fun函数开始执行,先print方法,然后进入while循环
3.遇到yield,然后把yield想成return,return了一个1之后,程序停止,需要注意:此时并没有执行赋值给result操作
4.执行print("----------------------")
5.执行run.send(2)方法,此时从上次停止的地方执行,也就是给result赋值,send(2)也就是result=2
6.print("result:{}".format(result)),注意此时的result=2
7.进入while True,遇到yield,也就是return了一个1之后,程序停止。
'''
斐波拉契队列:
def run(n):
a,b,c=0,1,1
while True:
if c > n:
return
else:
yield a
a,b=b,a+b
c+=1
a=run(10) //拿到生成器a
for i in a: //通过遍历的方式调用
print(i,end='\t')
#list(a) #通过list转换直接调用
'''
0 1 1 2 3 5 8 13 21 34
'''
生产者与消费者
import time
def consumer():
r = ''
while True:
n = yield r
if not n:
return
print('[CONSUMER] Consuming %s...' % n)
time.sleep(1)
r = '200 OK'
def produce(c):
next(c)
n = 0
while n < 5:
n = n + 1
print('[PRODUCER] Producing %s...' % n)
r = c.send(n)
print('[PRODUCER] Consumer return: %s' % r)
c.close()
if __name__=='__main__':
c = consumer()
produce(c)
close方法
def func():
one=yield '第一行'
yield '第二行'
yield '第三行'
f=func()
# print(f.send('111')) 报错,因为还没开启生成器
print(next(f))#第一行
print(next(f))#第二行
f.close()#关闭生成器
print(next(f)) #StopIteration报错,因为已经关闭了生成器
throw方法
def func():
try:
yield '第一行'
except Exception:
pass
yield '第二行'
yield '第三行'
f=func()
next(f)#第一行
#需要注意的是f.throw也相当于一次next,它是有返回值的,这里的返回值是'第二行'
f.throw(Exception,'error!!!')#自己给自己抛异常并捕获
next(f) #第三行
yield from
def fun1(arg):
yield arg
def fun2(arg):
yield from arg
for i in fun1(range(10)):
print(i)
'''
range(10)
'''
for i in fun2(range(10)):
print(i,end='\t')
'''
0 1 2 3 4 5 6 7 8 9
'''
- 这说明yield就是将range这个可迭代对象直接返回了
- 而yield from解析了range对象,将其中每一个item返回了
- yield from iterable本质上等于for item in iterable: yield item的缩写版 ,也就是说:yield from后面必须跟iterable对象
Async/Await
定义异步函数
协程需要驱动才能运行,直接使用send(None)async def async_function():
pass
因为生成器/协程在正常返回退出时会抛出一个StopIteration异常,而原来的返回值会存放在StopIteration对象的value属性中,通过以下捕获可以获取协程真正的返回值:print(async_function().send(None)) >>> StopIteration: 1
try:
async_function().send(None)
except StopIteration as e:
print(e.value)
await
在协程函数中,可以通过await语法来挂起自身的协程,并等待另一个协程完成直到返回结果
注意并非是异步处理的,注意挂起这个词 ```python async def async_function(): return 1
async def await_coroutine(): result = await async_function() return result
try: await_coroutine().send(None) except StopIteration as e: print(e.value) >>>1 ```
- 要注意的是,await语法只能出现在通过async修饰的函数中,否则会报SyntaxError错误。
- 而且await后面的对象需要是一个Awaitable,或者实现了相关的协议