异步编程 - Python中的yield from的用法?
迷茫
迷茫 2017-04-18 10:04:59
0
4
433

对于yield from目前我只知道这一种用法,我对它的理解也停留在yield from generator

In [1]: def reader():
   ...:     """A generator that fakes a read from a file, socket, etc."""
   ...:     for i in range(4):
   ...:         yield '<< %s' % i
   ...:         

In [2]: def reader_wrapper(g):
   ...:     yield from g
   ...:     

In [3]: wrap = reader_wrapper(reader())

In [4]: for i in wrap:
   ...:     print(i)
   ...:     
<< 0
<< 1
<< 2
<< 3

但是在廖雪峰的异步IO教程中看见一个yield from的新用法,请问下面这个yield from asyncio.sleep(1)是什么意思,asyncio.sleep(1)也是一个生成器吗?看官方文档也没有给出明确的解释,也是直接贴的代码,拜托大神解释一下!

import asyncio

@asyncio.coroutine
def hello():
    print("Hello world!")
    # 异步调用asyncio.sleep(1):
    r = yield from asyncio.sleep(1)
    print("Hello again!")

# 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(hello())
loop.close()
迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回覆(4)
刘奇

首先找到asyncio.sleep()函數的定義

coroutine asyncio.sleep(delay, result=None, *, loop=None)

也就是說這個函數是一個協程(coroutine)函數, 協程函數可以這樣呼叫來得到回傳值

result = await coroutine or result = yield from coroutine 

至於為什麼可以這麼用?

  1. await本身就是用在協程的一個關鍵字.

  2. 可以用yield關鍵字, 是因為coroutine的實現是基於生成器的(Generator-based),至於為什麼用yield from而不是原始的yieldyield
    可以看PEP380. 總而言之就是用yield來獲取協程的資訊比較麻煩,於是就加了個yield from 來簡化操作.

    https://www.python.org/dev/pe...

總結以下: 可以用yield是因為coroutine是generator-based的,所以你說sleep返回的是generator其實也不算錯麻煩, 你可以認為是語法糖.具體可以看​​PEP8. PS:最後再BB幾句, 這就是我為什麼不推薦看博客學習一門語言的原因, 同樣是免費的, 為什麼不選擇更加權威細緻的python官方文檔?

PHPzhong

協程的本質就是生成器

可以看看這個影片~
探索 Python 3.5 中 async/await 特性的實作

PHPzhong

為什麼要包裝一次了?

for i in reader():
    print(i)

這樣也能用啊?很納悶。 。 。

巴扎黑

可以看看 Python 作者寫的這篇文章,糙譯

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!