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) ...
非同期イテレータを使用しようとすると、「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)
エラーが発生します"async_generator" object is not an iterator
何かを Iterator と呼ぶのは、それがまったく同じインターフェースを持っているからだと思います。そのため、非同期イテレータを記述して、next() 呼び出しに大きく依存するフレームワークで使用できます。非同期を使用できるようにするためにコード全体を書き直す必要がある場合、Python の新しい機能は意味がありません。
何か見逃しているのでしょうか?
ありがとう!
ベストアンサー1
したがって、@bosnjak が言ったように、次の場合に async を使用できます。
async for ITEM in A_ITER:
BLOCK1
else: # optional
BLOCK2
ただし、手動で反復処理したい場合は、次のように記述するだけです。
it = async_iterator()
await it.__anext__()
しかし、そうすることはお勧めしません。
何かをイテレータと呼ぶのは、それがまったく同じインターフェースを持っているからだと思います。そのため、非同期イテレータを記述して、next()呼び出しに大きく依存するフレームワークで使用できます。
いいえ、実際には同じではありません。通常の同期イテレータと非同期イテレータには違いがあります。それにはいくつかの理由があります。
- Pythonコルーチンは内部的にジェネレータ上に構築されている
- Python の Zen によれば、明示的なものは暗黙的なものよりも優れています。そのため、実際にコードを中断できる場所を確認できます。
そのため、非同期イテレータではiter
とを使用next
することはできません。また、同期イテレータを期待するフレームワークで使用することもできません。したがって、コードを非同期にする場合は、非同期フレームワークも使用する必要があります。ここそれらはほとんどありません。
また、イテレータとジェネレータについても少し説明したいと思います。イテレータは、メソッドを持つ特別なオブジェクトです__iter__
。__next__
一方、ジェネレータは、yield
式を含む特別な関数です。すべてのジェネレータはイテレータであるが、その逆は成り立たない同じことが非同期イテレータとジェネレータにも適用されます。はい、Python 3.6 以降では非同期ジェネレータを作成できます。
async def ticker(delay, to):
for i in range(to):
yield i
await asyncio.sleep(delay)
あなたは読むことができますペップ525詳細については