2017-06-12 58 views
1

asyncio發佈之前,我一直使用基於生成器的協程。等待awaitable_object的值是多少?

現在我正在學習Python 3.5中引入的新功能async/await。這是我的測試程序之一。

class Await3: 
    def __init__(self, value): 
     self.value = value 
    def __await__(self): 
     return iter([self.value, self.value, self.value]) 

async def main_coroutine(): 
    x = await Await3('ABC') 
    print("x =", x) 

def dummy_scheduler(cobj): 
    snd = None 
    try: 
     while True: 
      aw = cobj.send(snd) 
      #snd = 42 
      print("got:", aw) 
    except StopIteration: 
     print("stop") 

dummy_scheduler(main_coroutine()) 

它的輸出是:

got: ABC 
got: ABC 
got: ABC 
x = None 
stop 

x值是await awaitable_object表達式的結果。爲什麼這個值是None,我怎樣才能將它設置爲我想要的值?

我能找到的所有值是await couroutine()的值取決於協程的返回值,但這不是我的情況。

取消註釋snd = 42不起作用。該錯誤是AttributeError: 'list_iterator' object has no attribute 'send'

回答

1

如果你要手動執行一類的__await__法,await表達的返回值在你的類將是什麼參數是用來構建StopIteration例外,在最後的一個實例如果沒有參數,則返回None

您無法控制StopIteration參數,如return iter(some_list)。你需要編寫你自己的迭代器。我說把它寫作爲發電機和return值:

class Await3: 
    def __init__(self, value): 
     self.value = value 
    def __await__(self): 
     yield self.value 
     yield self.value 
     yield self.value 
     return whatever 

這將引發StopIteration(whatever)結束迭代,但是如果你想要做的事情簡單的方法,你會寫在async功能第一個地方。