非同期ジェネレータはイテレータではありませんか? 質問する

非同期ジェネレータはイテレータではありませんか? 質問する

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()呼び出しに大きく依存するフレームワークで使用できます。

いいえ、実際には同じではありません。通常の同期イテレータと非同期イテレータには違いがあります。それにはいくつかの理由があります。

  1. Pythonコルーチンは内部的にジェネレータ上に構築されている
  2. 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詳細については

おすすめ記事