BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース Python 3.5、async/await非同期プログラミングをサポート予定

Python 3.5、async/await非同期プログラミングをサポート予定

原文(投稿日:2015/05/07)へのリンク

PEP (Python Enhancement Proposal) #0492によると、Python 3.5はasync/await構文を使った継続をサポートする予定だ。提案は継続をネイティブな言語機能とし、「一般的で親しみやすい非同期プログラミングのメンタルモデルを構築する」ことを狙っている。

新しく提案された継続を宣言するための構文は次のようなものだ。

async def read_data(db):
    pass

具体的に言うと、asyncは、たとえawait式を含んでいなくても、関数をコルーチンとして振舞うようにするキーワードだ。この関数を実行すると、コルーチンオブジェクトが返ってくる。

コルーチン本体では、awaitキーワードを使うことで、その式にコルーチンの実行をサスペンドさせ、処理が完了するのを待たせることができる。

async def read_data(db):
    data = await db.fetch('SELECT ...')
    ...

ジェネレータ拡張のおかげで、Pythonでもコルーチンを使うことができる。このPythonジェネレータはyieldyield from文が本体に登場すると、コルーチンとして扱う。

ジェネレータベースのコルーチンを使った例を以下に示す。

>>> def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator()
>>> for i in mygenerator:
...     print(i)
0
1
4

このコードでは、ジェネレータをforループで呼び出すたびに、ジェネレータのforループから新しい値が返される。

awaitの使用例はPEP #0492にある。

コルーチンの新しい提案には、ジェネレータとコルーチンを明確に分離するという目的がある。これによって次のようなメリットが期待されている。

  • 同じ構文を共有していないため、新しい開発者が2つの概念を理解しやすくなる。
  • リファクタリング中にうっかりコルーチンからyield文が取り除かれ、コルーチンがジェネレータとして扱われてしまうという「不明瞭なエラー」の原因を取り除く

async/await構文を使うことで、開発者はシーケンシャルにコードを書けるが、コンパイラはこれを一連のコルーチンで実装する。これによって並列実行を効果的に行うことができる。先ほどの例に戻ると、async/awaitを使うと、まるで各文がブロックして結果が利用可能になるまで待つかのように、複数のawait文をシーケンシャルに書くことができるが、実際にはブロックすることはない。

async def read_data(db):
    data = await db.fetch('SELECT ...')
    if (data...)
        await api.send(data ...')

この記事に星をつける

おすすめ度
スタイル

BT