1

イベント システムを実装しています。さまざまなコードがイベントを中央の場所に投稿し、そこでイベントがすべてのリスナーに配信されます。このアプローチの主な問題: イベント処理中に例外が発生すると、誰がイベントを投稿したのかわかりません。

だから私の質問は: Python 2.5 で誰がコンストラクターを呼び出したかを把握し、それを覚えておくための効率的な方法はありますか?

詳細情報: 簡単な方法は、traceback モジュールを使用してコンストラクターでスタックのコピーを取得し、それを記憶することです。残念ながら、この情報が必要になることはめったにないので、これをキャッシュする方法があったかどうか、または実際にこのデータが必要なまれなケースで最上位のスタック フレームを覚えて戻って作業できるかどうか疑問に思っています。

4

4 に答える 4

1
import sys
def get_caller(ext=False):
    """ Get the caller of the caller of this function. If the optional ext parameter is given, returns the line's text as well. """
    f=sys._getframe(2)
    s=(f.f_code.co_filename, f.f_lineno)
    del f
    if ext:
        import linecache
        s=(s[0], s[1], linecache.getline(s[0], s[1]))

    return s

def post_event(e):
    caller=get_caller(True)
    print "Event %r posted from %r"%(e, caller)

## Testing the functions.

def q():
    post_event("baz")

post_event("foo")
print "Hello!"
q()

結果は

Event 'foo' posted from ('getcaller.py', 20, 'post_event("foo")\n')
Hello!
Event 'baz' posted from ('getcaller.py', 17, '\tpost_event("baz")\n')
于 2009-04-04T09:41:55.083 に答える
1

呼び出し元のフレーム オブジェクトへの参照を単純に格納することもできますが、これはおそらく悪い考えです。これにより、フレームが生きたままになり、使用されるすべてのローカル変数への参照も保持されるため、大量のメモリを使用している場合はパフォーマンスに影響を与える可能性があり、ファイナライズに (誤って) 依存している場合はさらに悪い影響を与える可能性があります。ロックやファイルハンドルなどのリソースは、スコープ外になると破棄されます。

つまり、代わりにスタックトレースの文字列表現を保持する必要がありますが、これは目的には理想的ではありません (必要になることはめったにありませんが、取得するために実際に何らかの処理を行う必要があります)。残念ながら、これを回避する方法はあまりないようですが、何らかの構成オプションを設定するまでは無効にすることを検討できます。そうすれば、一般的なケースでパフォーマンスが向上しますが、障害を診断しようとするときに設定を有効にすることができます。

呼び出し関数だけ (または少数の親呼び出し元) でルートを区別するのに十分な場合 (つまり、func1() を介して呼び出された場合、トレースは常に同じであり、func2 -> func1() と func3() がない場合 - > func1() を区別するため)、呼び出しフレーム (または最後の 2 つの呼び出しフレームなど) のファイル名と行番号に基づいてハッシュを維持できます。ただし、これはおそらくあなたの状況と一致しません。そうでない場合は、偽のスタック トレースが発生することになります。

呼び出し元のフレームが必要な場合は、 を使用することをお勧めしますinspect.currentframe(depth)

于 2009-04-04T10:15:51.460 に答える
1

最も簡単な方法は、問題のイベントに ID フィールドを追加し、各イベント ソース (「イベント ソース」の定義がここで適切である場合) に、投稿時に一意の識別子を提供させることだと思います。行事。オーバーヘッドはわずかに増えますが、おそらく問題になるほどで​​はありません。イベントのソースを知ることが役立つ他の方法を見つけることができると思います。

于 2009-04-05T02:37:33.830 に答える
0

スタック トレースのハッシュをイベントのコンストラクターにアタッチし、ハッシュをキーとして実際のコンテンツを memcache に格納することは価値がある場合があります。

于 2009-04-04T09:06:57.617 に答える