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 1print("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:```pythondef fun():print("函数开始")while True:result = yield 1print("result:{}".format(result))run = fun()print(next(run))print("----------------------")print(run.send(2))'''函数开始1----------------------result:21''''''流程:1.run = fun(),得到生成器run2.调用next方法,fun函数开始执行,先print方法,然后进入while循环3.遇到yield,然后把yield想成return,return了一个1之后,程序停止,需要注意:此时并没有执行赋值给result操作4.执行print("----------------------")5.执行run.send(2)方法,此时从上次停止的地方执行,也就是给result赋值,send(2)也就是result=26.print("result:{}".format(result)),注意此时的result=27.进入while True,遇到yield,也就是return了一个1之后,程序停止。'''
斐波拉契队列:
def run(n):a,b,c=0,1,1while True:if c > n:returnelse:yield aa,b=b,a+bc+=1a=run(10) //拿到生成器afor i in a: //通过遍历的方式调用print(i,end='\t')#list(a) #通过list转换直接调用'''0 1 1 2 3 5 8 13 21 34'''
生产者与消费者
import timedef consumer():r = ''while True:n = yield rif not n:returnprint('[CONSUMER] Consuming %s...' % n)time.sleep(1)r = '200 OK'def produce(c):next(c)n = 0while n < 5:n = n + 1print('[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:passyield '第二行'yield '第三行'f=func()next(f)#第一行#需要注意的是f.throw也相当于一次next,它是有返回值的,这里的返回值是'第二行'f.throw(Exception,'error!!!')#自己给自己抛异常并捕获next(f) #第三行
yield from
def fun1(arg):yield argdef fun2(arg):yield from argfor 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,或者实现了相关的协议
