在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Python/ yeild from 后面的函數(shù)應(yīng)該返回什么?

yeild from 后面的函數(shù)應(yīng)該返回什么?

用asyncio實現(xiàn)了一個協(xié)程:

import threading
import asyncio

@asyncio.coroutine
def hello():
    print('Hello world! (%s)' % threading.currentThread())
    print(1)
    # asyncio.sleep(1)返回None
    r = yield from asyncio.sleep(1)
    print('Hello again! (%s)' % threading.currentThread())
    print(2)

loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

輸出:

Hello world! (<_MainThread(MainThread, started 6404)>)
1
Hello world! (<_MainThread(MainThread, started 6404)>)
1
Hello again! (<_MainThread(MainThread, started 6404)>)
2
Hello again! (<_MainThread(MainThread, started 6404)>)
2

可以看到是同一個進程運行了兩個協(xié)程,并且asyncio.sleep(1)這個函數(shù)模擬了一個一秒的IO等待,這就很迷了,我理解的是,程序運行到y(tǒng)eild from 就運行asyncio.sleep(1)這個函數(shù),然后等待IO返回,并去運行了另外一個hello(),待asyncio.sleep(1)運行完畢又接著運行hello()接下來的代碼
我就想了:

**可不可以自己寫個asyncio.sleep(1)函數(shù)啊,返回自己定義的值,賦值給r?**

但是并不是我想的那么簡單,報錯了,我寫的如下:

import threading
import asyncio
import time

def foo():
    # 返回'1'
    time.sleep(1)
    return '1'

@asyncio.coroutine
def hello():
    print('Hello world! (%s)' % threading.currentThread())
    print(1)
    r = yield from foo()
    print('Hello again! (%s)' % threading.currentThread())
    print(2)

loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

報錯如下:

Hello world! (<_MainThread(MainThread, started 6832)>)
1
Hello world! (<_MainThread(MainThread, started 6832)>)
1
Task exception was never retrieved
future: <Task finished coro=<hello() done, defined at test3.py:12> exception=RuntimeError("Task got bad yield: '1'",)>
Traceback (most recent call last):
  File "test3.py", line 16, in hello
    r = yield from foo()
RuntimeError: Task got bad yield: '1'
Task exception was never retrieved
future: <Task finished coro=<hello() done, defined at test3.py:12> exception=RuntimeError("Task got bad yield: '1'",)>
Traceback (most recent call last):
  File "test3.py", line 16, in hello
    r = yield from foo()
RuntimeError: Task got bad yield: '1'
    TypeError: 'int' object is not iterable

看提示是要返回一個iterable,改了一下:

def foo():
    # 返回一個iter
    time.sleep(1)
    return iter('1')

報錯:

Hello world! (<_MainThread(MainThread, started 6576)>)
1
Hello world! (<_MainThread(MainThread, started 6576)>)
1
Task exception was never retrieved
future: <Task finished coro=<hello() done, defined at test3.py:12> exception=RuntimeError("Task got bad yield: '1'",)>
Traceback (most recent call last):
  File "test3.py", line 16, in hello
    r = yield from foo()
RuntimeError: Task got bad yield: '1'
Task exception was never retrieved
future: <Task finished coro=<hello() done, defined at test3.py:12> exception=RuntimeError("Task got bad yield: '1'",)>
Traceback (most recent call last):
  File "test3.py", line 16, in hello
    r = yield from foo()
RuntimeError: Task got bad yield: '1'

看不懂RuntimeError: Task got bad yield: '1',求大佬解釋

幫我寫個

def foo():
    ??????

要是我的理解有錯也歡迎指出,謝謝各位

回答
編輯回答
毀與悔

你既然在異步框架用了協(xié)程,在hello前有異步裝飾器,那么你在yiled from后面跟的這個函數(shù)必須要有框架的異步裝飾器進行裝飾。就像如下:

@asyncio.coroutine
def foo():
    time.sleep(1)
    return "1"

想更深入地了解裝飾器的作用,你就需要自己去搜搜資料學(xué)了。一般異步框架的話,只要這么裝飾起來用就OK了。

2017年4月1日 19:52