6

標準スレッドライブラリ ( Python 2.6 )のコードの一部を読んでいて、疑問に思ったコードがありました。次の構造に短縮できます ( threading.pyの __bootstrap_inner メソッドと比較してください)。

def foo():
    exc_type, exc_value, exc_tb = sys.exc_info()
    try:
        # some code
    except:
        # some code
    finally:
        del exc_type, exc_value, exc_tb

fooこれらの変数はスコープ外にはなりません。最後にこれらの参照を削除する理由はありますか?

4

1 に答える 1

8

はい、少なくともexc_tb; traceback オブジェクトは現在のフレームへの参照を保持しているため、これが循環参照になります。

ローカル参照を削除することで、その輪を壊すことができるので、ガベージ コレクターが削除できることを期待して信頼する必要はありません。

sys.exc_info()関数ドキュメントから:

警告: 例外を処理している関数内のローカル変数にトレースバックの戻り値を代入すると、循環参照が発生します。これにより、同じ関数内のローカル変数またはトレースバックによって参照されるものがガベージ コレクションされるのを防ぐことができます。ほとんどの関数はトレースバックにアクセスする必要がないため、最善の解決策はexctype, value = sys.exc_info()[:2]、例外の型と値のみを抽出するようなものを使用することです。トレースバックが必要な場合は、使用後に削除するか ( try...finallyステートメントで行うのが最適です) exc_info()、例外を処理しない関数を呼び出すようにしてください。

于 2013-02-14T09:14:03.613 に答える