非同期待ちPython連携

4631 ワード

Pythonでは、非同期処理のためのコラボレーションがサポートされています.しかし、最近では、Pythonの言語構造を全面的に改善するために、現在のようにジェネレータの1つのタイプではなく、協程を追加することを提案されています.さらに、2つの新しいキーワードである非同期(async)と待機(await)は、Pythonに追加して協程をサポートする必要があります.
非同期待ちPython連携
協程をよく知らない人もいるかもしれませんが、実は協程の原理は簡単で、例えば、10人が食堂に行って食事をするとしたら、この食堂は貧乏で、1つの食事窓口と1人の食事をするおばさんしかいません.この10人は食欲があって、1人5つの料理を注文しますが、この10人はためらうのが好きで、注文するときは1つの料理を注文してから次の料理を注文したいので、後ろの人は焦っています.
これでずっと立っているのも問題ではないので、料理を打つおばさんは誰かが5秒ためらっているのを見て、彼を列の末尾に並べて、他の人に先に料理を打たせて、彼の番になったら彼も何かおいしいものを食べたくないところだった.これは确かにいい方法ですが、一つの欠点があります.それは料理をするおばさんが一人一人を5秒待っていることです.もしあの人が5秒以内に何を食べるかを决めなかったら、実はこの5秒は无駄になります.一人で1つの料理を注文するのは5秒の無駄で、10人は一人で5つの料理を注文すると「料理が冷めたら」無駄になります.
どうすればいいの?おばさんはまた言いました:みんな学生で、学生は自覚しなければなりません.私はこれからも自発的にあなたたちを最後まで並ばせません.もしあなたたちが自分がためらうと思ったら、自分から直接料理を注文して後ろに立って、次の列に並んだときもおいしいものが欲しくありません.
この方法はやはり効果的で、みんなが料理を注文して最初に考えたことは次の料理ではなく、自分がためらうかどうかで、ためらうならそのまま列の後ろに並んで、そうでなければ注文を続けます.これでチーム全体の効率が自然に高くなります.
この例では、並んでいるおばさんの叫び声が私たちのCPU中断で、コンテキストを切り替えるために使われています.食事をする学生はtaskです.誰もが自分が窓を譲るかどうかを決める行為は、実は私たちの協力の核心思想である.
OK,トピックに戻ると,コヒーレンスはコードの様々な事前定義された位置で実行を一時停止および復元できる関数であり,無意味なスケジューリングを回避し,コード性能を向上させる.サブプログラムは特殊な協同プログラムであり、単一のエントリのみがコールバックによって実行されます.Pythonのコンシステント「既存のジェネレータベースのコンシステントと新しく提案されたコンシステント」は一般的な意味でのコンシステントではありません.なぜなら、一時停止を実行する際に、通常のように他のコンシステントに制御権を渡すのではなく、呼び出し者に制御権を渡すしかないからです.イベントループを補助し、特にI/Oにおいて、コプロセッサを非同期処理に使用することができる.
Pythonが現在サポートしているコパスは、PEP 342エンハンスメントジェネレータに基づいて、Python 2.5バージョンで採用され始めました.このPEPはyield文を式に変更し、生成器にいくつかの新しい方法「send(),throw(),and close()」を追加し、同時にclose()方法が生成器がゴミ回収段階に入ったときに呼び出されることを確保した.この機能はPython 3.3バージョンのPEP 380でさらに強化され、yield式を追加することで、ジェネレータが別のジェネレータ「すなわちサブジェネレータ」に一部の機能を付与できるようになった.
以上の方法は、コードセグメントのどこで非同期呼び出しを行うかを困惑させ、制限されるように、コヒーレントをジェネレータに依存させる.特に、withおよびfor宣言は、非同期呼び出しに対して理論的に使用可能であるが、Python構文は、それらの場所でyield式を使用することが許されないため、非同期呼び出しを行うことができない.さらに、コヒーレンスの再構成がyieldまたはyield fromを関数から削除すると、コヒーレンスと見なされなくなり、明らかでないエラーが発生します.asyncioモジュールは@asyncio.coroutine装飾器によってこの方面の不足を補う.
PEP 492は、以上のすべての問題を解決することを目的とする.そのアイデアはYury Selivanovが4月中旬に提出したpython-ideasメールリストに由来し、多くの人に人気を集めている.5月5日、Guido van RossumはPython 3.5バージョンに追加することに同意した.それだけでなく、5月12日に実行されます.すべてが急速に進んでいるが、最終的にはpython-ideaとpython-devの面で情熱的な議論を引き起こしている.
文法の観点から見ると、変化はかなり簡単です.
    async def read_data(db):
        data = await db.fetch('SELECT ...')
    ...

この例「PEPに由来する」は、新しいasync defコンストラクション関数を使用してread_data()コヒーレンスを作成します.await式は、read_data()が完了し、その結果が返されるまで、db.fetch()の実行を一時停止します.awaitはawait ableに似ていますが、パラメータawaitableが確保されます.
他にもいくつかの異なるタイプのawaitableがあります.1つは、ローカル協同プログラムが呼び出された後にawaitableとして返され、ジェネレータベースでyeild fromで装飾された協同オブジェクトである.もう1つは、将来完了する操作を表す未来オブジェクトであり、awaitableでもあります.@types.coroutineメソッドはawaitableのオブジェクトに表示されます.
しかし、ある言語に新しいキーワードを追加すると、キーワード名と同じ変数が文法エラーになるという問題が発生します.この問題を回避するために、Python 3.5と3.6のバージョンでは、「softly deprecate」「やさしく捨てる」asyncとwaitを文法エラーとしない変数名として使用します.解析器はasync defブロックを追跡し、ブロック内のキーワードを区別して、既存の使用を継続的に有効にします.
新しい特性では、非同期には、非同期コンテンツマネージャ(with)と反復器(for)の2つの新しい用途があります.コヒーレンスでは、この2つの構造関数の例は次のとおりです.
    async def commit(session, data):
    ...

    async with session.transaction():
        ...
        await session.update(data)
        ...
        ...
        async for row in Cursor():
            print(row)

非同期コンテンツマネージャは、2つの非同期メソッド、__await __()および__aenter __()を実装し、awaitablesに戻る必要があります.非同期反復器は、__aexit __()および__aiter __()を実現しなければならない.これらの方法は、既存の同期コンテンツマネージャと反復器の非同期バージョンです.
これまで主な議論は、実行を延期した「cofunction」機能PEP 3152がより良い出発点になるかどうかであり、このPEPの著者Greg Ewingはこの問題を提起した.しかし、Selivanovが提案した文法がcodef、cocallに適していると考える人もいれば、Ewingの提案にもっと賛成する人もいる.このように何度も論争を繰り返した.cofunctionの構文は,場合によってはかなり複雑でPython言語の特性に合わないと考える人もいる.その後Van Rossumはcofunctions文法に存在する問題をまとめ,この方法の採用を拒否した.
また、非同期機能の追加に関するいくつかの提案は議論に値するが、緊急ではない.キーワードの議論には本末転倒がある.awaitの優先度の問題もしばらく議論された結果,yeildとyeild fromとは異なり最低優先度であり,awaitはより高い優先度を有した.
しかし、Mark Shannon氏は、Selivanovの提案を実現するには、新しい文法を追加する必要はないと愚痴をこぼしている.他の人も同様の意見を出したが、Selivanovや他の支持者は反論しなかった.重要なのは、協同プログラムの作成を簡素化することです.それ以外に、Van Rossumは協同プログラムが一時停止する位置が明らかになることを望んで、コードを見て発見することができます:
新しい文法こそPEPの存在意義です.構文構造で協程の懸垂点を判断できることを望んでいます.
2、3週間後、複数のバージョンのPEPが発表され、多くの議論が起こった.Selivanovは彼の考えを辛抱強く説明し、フィードバックに基づいて自分の考えを修正し続けた.非同期コラボレーション特性はPython言語の将来にとって極めて重要であり,探索過程全体が速く,順調である可能性が高い.しかし、Python開発者たちがこれらの考えを実践するには、まだ時間がかかる可能性が高い.
原文住所:Python coroutines with async and await
参考記事:Pythonにおけるyieldと協程の理解
本文はOneAPMエンジニアの翻訳です.OneAPMはアプリケーションパフォーマンス管理分野の新興リーダー企業であり、企業ユーザーと開発者が簡単に実現できる:遅いプログラムコードとSQL文のリアルタイムキャプチャ.詳細については、OneAPM公式ブログをご覧ください.