use*_*011 14 python python-asyncio
在Python中,您可以编写一个可迭代的生成器,如:
def generate(count):
for x in range(count):
yield x
# as an iterator you can apply the function next() to get the values.
it = generate(10)
r0 = next(it)
r1 = next(it) ...
Run Code Online (Sandbox Code Playgroud)
尝试使用异步迭代器时,会出现'yield inside async'错误.建议的解决方案是实现自己的生成器:
class async_generator:
def __aiter__(self):
return self
async def __anext__(self):
await asyncio.sleep()
return random.randint(0, 10)
# But when you try to get the next element
it = async_generator(10)
r0 = next(it)
Run Code Online (Sandbox Code Playgroud)
你得到错误"'async_generator'对象不是迭代器"
我认为如果你打算把它称为迭代器,因为它具有完全相同的接口,所以我可以编写异步迭代器并在依赖于next()调用的框架上使用.如果您需要重写整个代码以便能够使用异步,那么任何新的Python功能都是没有意义的.
我错过了什么吗?
谢谢!
小智 10
所以,正如@bosnjak所说,你可以使用async:
async for ITEM in A_ITER:
BLOCK1
else: # optional
BLOCK2
Run Code Online (Sandbox Code Playgroud)
但是如果你想手动迭代,你可以简单地写:
it = async_iterator()
await it.__anext__()
Run Code Online (Sandbox Code Playgroud)
但我不建议这样做.
我认为,如果你要调用Iterator,因为它具有完全相同的接口,所以我可以编写异步迭代器并在依赖于next()调用的框架上使用
不,实际上它不一样.常规同步迭代器和异步迭代器之间存在差异.而且原因很少:
这就是为什么不可能使用iter和next使用异步迭代器.并且您不能将它们用于需要同步迭代器的框架.因此,如果要使代码异步,则必须使用异步框架.这里有一些.
另外,我想谈谈迭代器和生成器.迭代器是一个具有__iter__和__next__方法的特殊对象.而generator是一个包含yield表达式的特殊函数.每个生成器都是迭代器,但反之亦然.异步迭代器和生成器也可以接受同样的事情.是的,因为python 3.6你可以编写异步生成器!
async def ticker(delay, to):
for i in range(to):
yield i
await asyncio.sleep(delay)
Run Code Online (Sandbox Code Playgroud)
您可以阅读PEP 525了解更多详情
我相信为异步生成器引入了新的声明:
async for TARGET in ITER:
BLOCK
else:
BLOCK2
Run Code Online (Sandbox Code Playgroud)
根据PEP 492。
基本上,这意味着您应该执行以下操作:
async for number in generate(10):
print(number)
Run Code Online (Sandbox Code Playgroud)
原生协程对象不实现iter和next 方法。因此,它们不能被迭代或传递给iter(),list(),tuple()和其他内置函数。它们也不能在for..in循环中使用。尝试在本机协程对象上使用iter或next会导致TypeError。
在 python 3.10+ 中,您可以使用anext https://docs.python.org/3/library/functions.html#anext
我修改了前面的示例来说明如何anext工作:
import asyncio
async def ticker(to):
for i in range(to):
await asyncio.sleep(1)
yield i
async def main():
# get only first, failed if nothing yield
await anext(ticker(3))
# get only first or default (77)
await anext(ticker(3), 77)
# iterate through all
async for i in ticker(3):
print(i)
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9330 次 |
| 最近记录: |