[解決済み] コルーチン vs 継続 vs ジェネレータ
質問
コルーチン、継続、ジェネレータの違いは何ですか?
どのように解決するのですか?
まず、最も単純なケースであるジェネレータから説明します。zvolkov が言ったように、ジェネレータは繰り返し呼び出すことができる関数/オブジェクトで、呼び出されると値を返して(yield)、実行を一時停止します。再び呼び出されると、最後に実行を中断したところから起動し、再び実行を行います。
ジェネレーターは、本質的には、(非対称の)コルーチンを切り詰めたものです。コルーチンとジェネレーターの違いは、コルーチンは最初に呼び出された後に引数を受け付けることができるのに対し、ジェネレーターは引数を受け付けることができない点です。
コルーチンを使った簡単な例を思いつくのはちょっと難しいのですが、ここでは私のベスト・トライを紹介します。このPythonのコードを例にしてみましょう。
def my_coroutine_body(*args):
while True:
# Do some funky stuff
*args = yield value_im_returning
# Do some more funky stuff
my_coro = make_coroutine(my_coroutine_body)
x = 0
while True:
# The coroutine does some funky stuff to x, and returns a new value.
x = my_coro(x)
print x
コルーチンが使われる例として、レキサーとパーサーがあります。コルーチンが言語内にないか、何らかの方法でエミュレートされていない場合、レキシングとパーシングのコードは、実際には2つの別々の関心事であるにもかかわらず、一緒に混在させる必要があるのです。しかし、コルーチンを使えば、レキシングとパーシングのコードを分離することができるのです。
(対称型コルーチンと非対称型コルーチンの違いについては、これから説明します。また、非対称コルーチンはジェネレータに最も似ており、理解しやすい。私は、Pythonで非対称コルーチンを実装する方法の概要を説明しました)。
コンティニュエーションは、実はとてもシンプルな生き物なんです。プログラムの別のポイントを表す関数で、それを呼び出すと、その関数が表すポイントに自動的に実行が切り替わるだけです。あなたは毎日、気づかないうちに、非常に限定されたバージョンを使っているのです。例えば、例外は一種のインサイドアウトの継続と考えることができる。Pythonをベースにした継続の疑似コードの例をあげます。
Pythonに
callcc()
この関数は2つの引数を取り、1つ目は関数、2つ目は関数を呼び出すための引数のリストです。この関数の唯一の制限は、最後に受け取る引数が関数であることです(これは私たちの現在の継続になります)。
def foo(x, y, cc):
cc(max(x, y))
biggest = callcc(foo, [23, 42])
print biggest
どうなるかというと
callcc()
は順番に
foo()
を、現在の継続時間 (
cc
)、つまり、プログラム中のどの地点で
callcc()
が呼び出されました。このとき
foo()
は現在の継続を呼び出すので、本質的には
callcc()
を呼び出すと、スタックをロールバックして現在の継続が作成された場所、つまり、あなたが
callcc()
.
この結果、私たちの仮想的な Python バリアントは、次のように表示します。
'42'
.
私の説明はかなり改善できるはずです!お役に立てれば幸いです。
関連
-
Python jiabaライブラリの使用方法について説明
-
[解決済み】TypeErrorの修正方法。Unicodeオブジェクトは、ハッシュ化する前にエンコードする必要がある?
-
[解決済み】なぜ「LinAlgError: Grangercausalitytestsから「Singular matrix」と表示されるのはなぜですか?
-
[解決済み] staticmethodとclassmethodの違いについて
-
[解決済み] Pythonのリストメソッドであるappendとextendの違いは何ですか?
-
[解決済み】if __name__ == "__main__": は何をするのでしょうか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】forループを使った辞書の反復処理
-
[解決済み】__str__と__repr__の違いは何ですか?
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
pythonサイクルタスクスケジューリングツール スケジュール詳解
-
Python 可視化 big_screen ライブラリ サンプル 詳細
-
PyQt5はユーザーログインGUIインターフェースとログイン後のジャンプを実装しています。
-
PythonによるExcelファイルの一括操作の説明
-
Python LeNetネットワークの説明とpytorchでの実装
-
[解決済み】Pythonスクリプトで「Expected 2D array, got 1D array instead: 」というエラーが発生?
-
[解決済み】Django: ImproperlyConfigured: SECRET_KEY 設定は空であってはならない
-
[解決済み] 'DataFrame' オブジェクトに 'sort' 属性がない
-
[解決済み】Python - "ValueError: not enough values to unpack (expected 2, got 1)" の修正方法 [閉店].
-
[解決済み】Flaskのテンプレートが見つからない【重複あり