Python 3.5、async/await非同期プログラミングをサポート予定
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ジェネレータはyield
やyield 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 ...')
特集コンテンツ一覧
実例で学ぶGS Collections – Part 2
Donald Raab 2014年11月20日 午後8時3分
実例で学ぶGS Collections – Part 1
Donald Raab 2014年10月23日 午前2時24分
プロジェクトインセプション - 協力体制を作るミーティングの方法
James Bayer 2014年10月14日 午後7時57分
カンバンはどのように動作するか
Amr Noaman Abdel-Hamid 2014年9月7日 午後7時43分
自己組織化チームはなぜ必要か?
Sigi Kaltenecker and Peter Hundermark 2014年8月31日 午前2時2分
こんにちは
コメントするには InfoQアカウントの登録 または ログイン が必要です。InfoQ に登録するとさまざまなことができます。アカウント登録をしてInfoQをお楽しみください。
あなたの意見をお聞かせください。