1

通常の関数呼び出しでは、プログラム状態はほとんどが単純な呼び出しスタックによって記述されます。キャッチされない例外の後にトレースバックとして出力され、inspect.stackで検査され、ブレークポイントの後にデバッガに表示されます。ジェネレータ/コルーチンの存在下でプログラム状態を検査するにはどうすればよいですか?

ジェネレータ、ジェネレータベースのクルーチュール、およびコルーチンをベースにしたコルーチンの存在下では、コールスタックは十分ではないと思います。精神的にプログラムの状態を視覚化するための良い方法は何ですか?実行時にどのように検査するのですか?

ファンクションinspect.getgeneratorstateinspect.getcoroutinestateがありますが、ジェネレータ/コルーチンが作成、実行、中断、またはクローズされているかどうかに関する情報のみを提供します。状態がRUNNINGの場合、ジェネレータまたはコルーチンが現在実行している実際の行番号と、呼び出された可能性のある他の関数に対応するスタックフレームを調べることができます。それがSUSPENDEDの場合は、データを送信したか生成した他のジェネレータ/コルーチンを調べたいと思います。

編集:私はこのexcellent articleに私がこの質問で尋ねたすべてを説明することを指摘した関連question on SOを見つけました。

+0

ブレークポイントにスタックを表示するか、 'async def'ベースのコルーチン内の例外ハンドラで' traceback.print_stack() 'を呼び出そうとしましたか? –

+0

@AndrewSvetlovはい。スタックに表示されるのは、スタックの一番下のイベントループ、真ん中のイベントハンドラコード、スタックの一番上にある実際の非同期コルーチンコードです。他のコルーチンについては何も見ません。別の積み重ねや何かがあるはずだが、私の心の中にはっきりとしたイメージを作ることさえできないようだ。 – max

答えて

1

ジェネレータとコルーチンのすべてのインスタンスをすべての "従来の"フレームで検索するだけです(全フレームのすべてのオブジェクトで再帰的に検索するかガベージコレクタ(gc)を使用しないでください)これらのすべてのインスタンスへの参照を取得するモジュール)

ジェネレータとコルーチンには、それぞれgi_frame属性とcr_frame属性があります。

+1

そして明らかに '.gi_yieldfrom'と' .cr_await'はジェネレータ/コルーチンの階層をナビゲートするのに役立ちます。 – max

関連する問題