2

次のコードを使用します。

def A():
   try:
      B()
   except Exception:
      pass

def B():
   C()

def C():
   print exception_handling_pointer()

A()

この関数exception_handling_pointerは、この特定の例外が最初にチェックされて処理される関数へのポインターを返す必要があります。つまり、この場合、出力は sth になると予想されます。お気に入り:

<function A ...>

関数をどのように実装できますexception_handling_pointerか?

4

2 に答える 2

3

実際に例外を発生させずに、例外が処理される場所を決定することはできません。これはここで簡単に見ることができます:

try: 
    raise input('Raise which?')
except input('Catch which?') as e: 
    pass`

必要なことを行う関数は、ここでユーザー入力を予測する必要があります。全体の努力は無駄であり、Python はそれをサポートしていません。

とにかく、興味本位で聞いていただければ幸いです...

于 2010-11-28T18:03:46.860 に答える
2

これは非常にばかげたことであり、ほとんどの人はそれを行うことはできないと言うでしょう (THC4k は、一般的なケースでこれの説得力のある証拠を提供します)。

ステップ1。フレームをさかのぼる必要があります。sys._getframeorを使用して最初のものを取得しinspect.currentframeます (誰にも言わないでください。2 番目は最初のエイリアスのようです)。次に、それらを反復処理できますf.f_back

ステップ2。それぞれにf.f_lasti指示があります。これは、フレームで実行された最後の命令です。保存する必要があります。次に、バイトコードをさかのぼって - f.f_code.co_code- f.f_lasti` のSETUP_EXCEPTにジャンプする引数を持つオペコードを探します。分岐点は例外処理です。

ステップ3。これは、より曖昧になるところです。重要なのは、実際の比較演算はCOMPARE_OP、引数として 10 を持つ a になるということです。私が見たすべてのケースで、その後にPOP_JUMP_IF_FALSE. exceptこれにより、次の節または節にジャンプしfinallyます。例外をスタックにロードするコードが先行します。1 つしかない場合は、ストレートLOAD_GLOBALまたはLOAD_GLOBALor LOAD_FAST(例外のあるモジュールがグローバルかローカルかによって異なります) の後にLOAD_ATTR. 一致する例外が複数ある場合は、一連のロード操作の後にBUILD_TUPLE(慣用的な) またはBUILD_LIST(その他の奇妙な状況または非慣用的な状況) が続きます。

ポイントは、LOAD_X手順を確認して、名前と一致する例外を比較できることです。name のみを比較していることに注意してください。彼らが名前を再割り当てした場合、あなたは SOL です。

ステップ4。一致が見つかったとしましょう。次に、関数オブジェクトが必要です。これを行うために私が考えることができる最良の方法は次のとおりです (私は更新する権利を留保します):f.f_codeにはco_filename属性があります。ループすることができsys.modules、それぞれに__name__属性があります。を使用する必要があることを念頭に置いて、2 つを比較できます__name__.endswith(co_filename)。一致すると、モジュール関数をループして、それらのf.func_code.co_firstlineno属性をフレームと比較できますf.f_lineno属性。試合に勝てば、自分の役割を果たします。モジュール内の各クラスのメソッドもループする必要があります。ネストされた関数で処理が発生している可能性があります。その場合、私は現在、賢明なことを考えることはできません。(それはまったく別のバイトコードのハックであり、それ自体が不安定になります)

ステップ5。利益。

これにより、これを行う方法の一般的なアイデアが得られるはずです。あなたがそれを行うことができないあらゆる種類のコーナーケースがありますが、通常のユースケースでは、それをやってのけることができるはずです. それができることに依存するコードを書くと、それ壊れます。これは一種の「できるからやる」ということです。

于 2010-11-28T21:39:53.067 に答える