12

(注:この質問は、APIの設計に関するものであり、実装方法に関するものではありません。つまり、APIのクライアントがここで見るものだけを気にし、それを機能させるために何をしなければならないかは気にしません。)

簡単に言えば、Pythonで明示的な先物(別名promise、別名deferred、別名tasks-名前はフレームワークによって異なります)の確立されたパターン(ある場合)を知りたいです。以下は、より詳細な説明です。

次のような単純なPythonAPIについて考えてみます。

def read_line():
   ...
s = read_line()
print(s)

これは同期バージョンです-回線がまだ利用できない場合はブロックされます。ここで、操作が完了したときに呼び出されるコールバックを登録できる、対応する非同期(非ブロッキング)バージョンを提供するとします。たとえば、単純なバージョンは次のようになります。

def read_line_async(callback):
   ...
read_line_async(lambda s: print(s))

現在、他の言語やフレームワークでは、そのようなAPIに対して、既存の必須または少なくとも十分に確立されたパターンが存在することがよくあります。たとえば、バージョン4より前の.NETでは、通常、BeginReadLine/EndReadLineメソッドのペアを提供し、ストックIAsyncResultインターフェイスを使用してコールバックを登録し、結果の値を渡します。.NET 4以降ではSystem.Threading.Tasks、を使用して、すべてのタスク結合演算子(WhenAllなど)を有効にし、C#5.0async機能に接続します。

別の例として、JavaScriptでは、これを標準ライブラリでカバーするものは何もありませんが、jQueryは、現在個別に指定されている「deferredpromise」インターフェースを普及させました。したがってreadLine、JSで非同期を作成する場合は、名前を付けて、戻り値にメソッドreadLineAsyncを実装します。then

Pythonの土地で確立されたパターンがあるとすれば、それは何ですか?標準ライブラリを見ると、非同期APIを提供するいくつかのモジュールがありますが、それらの間に一貫したパターンはなく、「タスク」または「約束」の標準化されたプロトコルのようなものはありません。おそらく、人気のあるサードパーティのライブラリから派生できるパターンがいくつかありますか?

Twistedの(このコンテキストでよく言及される)Deferedクラスも見ました、汎用のpromise API用に過剰に設計されており、このライブラリの特定のニーズに適合しているようです。クライアントがアプリケーションで両方のライブラリを一緒に使用する場合、私たちの約束がうまく相互運用できるように、(それらに依存することなく)インターフェイスを簡単に複製できるもののようには見えません。直接依存することなくコピー(および相互運用)できる、このために明示的に設計されたAPIを備えた他の人気のあるライブラリまたはフレームワークはありますか?

4

3 に答える 3

6

さて、クラスを持つ PEP-3148 を見つけましFuture。私が見る限り、適切なインスタンスは によってのみ作成されExecutor、同期呼び出しをバックグラウンド スレッドに移動するなどして、既存の同期 API を非同期に変換するクラスであるため、このままではまったく使用できません。ただし、Futureオブジェクトが提供するメソッドを正確に複製できます。つまり、(ブロック) 結果のクエリ、キャンセル、およびコールバックの追加など、私が期待するものと非常によく一致します。

これは合理的なアプローチのように聞こえますか? おそらく、Python コレクションにABCがあるように、一般的な「未来」の概念の抽象基本クラスを Python 標準ライブラリに追加するという提案が伴う必要があります。

于 2011-09-02T04:26:04.413 に答える
1

ヒントについては、さまざまな「サーバー」ライブラリを参照してください。

良い例はBaseHTTPServer です

具体的には、HTTPServerクラス定義は、「ハンドラー クラス」がどのように提供されるかを示しています。

各リクエストは、ハンドラー クラスのインスタンスをインスタンス化します。次に、そのオブジェクトがリクエストを処理します。

「コールバック」を使用して「非同期 I/O」を記述したい場合はReadHandler、リーダーにクラスを提供します。

class AsyncReadHandler( object ):
    def input( self, line, server ):
        print( line )

read_line_async( AsyncReadHandler )

そのようなものは、いくつかの確立された設計パターンに従います。

于 2011-09-02T02:14:37.133 に答える
0

もうデコレータを見ましたか?

from threading import Thread

def addCallback(function):
    def result(parameters,callback):
        # Run the function.
        result = function(parameters)
        # Run the callback asynchronously.
        Thread(target=callback).start()
        # Run the callback synchronously.
        #callback()
        # Return the value of the function.
        return result
    return result

@ addCallback
def echo(value):
    print value

def callback():
    print 'Callback'

echo('Hello World!',callback)
于 2011-09-02T04:52:54.287 に答える