2017-03-06 75 views
0

我正在學習Python的相對較新的異步功能。我發現這在PEP 492來自Python 3的TypeError異步循環

The following is a utility class that transforms a regular iterable to an asynchronous one. While this is not a very useful thing to do, the code illustrates the relationship between regular and asynchronous iterators.

class AsyncIteratorWrapper: 
    def __init__(self, obj): 
     self._it = iter(obj) 

    def __aiter__(self): 
     return self 

    async def __anext__(self): 
     try: 
      value = next(self._it) 
     except StopIteration: 
      raise StopAsyncIteration 
     return value 

async for letter in AsyncIteratorWrapper("abc"): 
    print(letter) 

我試圖通過增加給定async for循環的功能,然後調用,使用一個事件循環運行該代碼。

完整的示例代碼(在解釋器中運行):

class AsyncIteratorWrapper: 
    def __init__(self, obj): 
     self._it = iter(obj) 
    def __aiter__(self): 
     return self 
    async def __anext__(self): 
     try: 
      value = next(self._it) 
     except StopIteration: 
      raise StopAsyncIteration 
     return value 

async def aprint(str): 
    async for letter in AsyncIteratorWrapper(str): 
    print(letter) 

import asyncio 
loop = asyncio.get_event_loop() 
co = aprint("abcde") 
loop.run_until_complete(co) 

不過,我得到一個錯誤:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/opt/rh/rh-python35/root/usr/lib64/python3.5/asyncio/base_events.py", line 337, in run_until_complete 
    return future.result() 
    File "/opt/rh/rh-python35/root/usr/lib64/python3.5/asyncio/futures.py", line 274, in result 
    raise self._exception 
    File "/opt/rh/rh-python35/root/usr/lib64/python3.5/asyncio/tasks.py", line 239, in _step 
    result = coro.send(None) 
    File "<stdin>", line 2, in aprint 
TypeError: 'async for' received an invalid object from __aiter__: AsyncIteratorWrapper 

我在做什麼錯?這個例子如何解決?我感到有點驚訝,PEP中的代碼失敗了。

我正在使用python版本3.5.1。

+0

它正在處理'python3.6' – sobolevn

+1

也可以使用3.5 - 查看更改日誌我發現「版本3.5.2中已更改:從CPython 3.5.2開始,__aiter__可以直接返回異步迭代器。」 – Orange

+0

對於''__aiter__'中的幾個版本假設是異步的,但是隨後symantics變成直接返回異步迭代,所以只需更新到更新版本的python,你應該沒問題。 –

回答

0

您使用的代碼適用於python 3.5.2+。

從Python 3.5.2 __aiter__可以直接返回異步迭代器。 More here

您收到的錯誤是由於較舊的python(3.5.1),因此它返回了錯誤的類型。