BT

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

作者: Sergio De Simone , 翻訳者 笹井 崇司 投稿日 2015年5月10日 |

原文(投稿日: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 ...')

こんにちは

コメントするには InfoQアカウントの登録 または が必要です。InfoQ に登録するとさまざまなことができます。

アカウント登録をしてInfoQをお楽しみください。

あなたの意見をお聞かせください。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする
コミュニティコメント

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

ディスカッション

特集コンテンツ一覧

サイト全般について
バグ
広告
記事
Marketing
InfoQ.com and all content copyright © 2006-2015 C4Media Inc. InfoQ.com and 株式会社豆蔵 InfoQ Japan hosted at Contegix, the best ISP we've ever worked with.
プライバシー
BT