Frage

Nehmen Sie diesen Code ein:

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

def B():
   C()

def C():
   print exception_handling_pointer()

A()

Die Funktion exception_handling_pointer sollte ich einen Zeiger auf die Funktion, wo diese spezifische Ausnahme zuerst behandelt wird geprüft würde zu werden. Das heißt, in diesem Fall würde ich die Ausgabe erwartet etw. wie:

<function A ...>

Wie kann ich die Funktion exception_handling_pointer implementieren?

War es hilfreich?

Lösung

Dies ist eine ziemlich dumme Sache zu tun und die meisten Leute würden sagen, dass es nicht getan werden kann (THC4k gibt zwingende Beweise dafür für die allgemeine cace), aber es macht Spaß Sound und soll perfekt machbar sein in vielen realen Einsatz- Fälle.

Schritt 1: . Sie müssen sich durch den Rahmen Schritt zurück. Holen Sie sich das erste mit sys._getframe oder inspect.currentframe (ich niemand sagen, scheint der zweiten in die erste aliased). Dann können Sie durch sie durchlaufen mit f.f_back

Schritt 2 . Jeder wird eine f.f_lasti Anweisung haben. Dies ist der letzte Befehl, der in dem Rahmen ausgeführt wurde. Sie werden es speichern müssen. Nun gehen Sie rückwärts gehen durch den Bytecode - f.f_code.co_code - und suchen nach einem SETUP_EXCEPT Opcode mit einem Argument, das zu springt nach f.f_lasti`. Der Sprungpunkt ist die Ausnahmebehandlung.

Schritt 3: . Dies ist, wo es wird unschärfer. Der Schlüssel ist, dass die Ist-Vergleichsoperation ein COMPARE_OP mit einem 10 als Argument sein wird. In allen Fällen, dass ich gesehen habe, ist es von einem POP_JUMP_IF_FALSE gefolgt. Diese springt in der nächsten except Klausel oder die finally Klausel. Es wird durch den Code vorangestellt werden, dass Lasten lädt die Ausnahmen auf den Stapel. Wenn es nur eine ist, dann wird es ein gerade LOAD_GLOBAL oder ein LOAD_GLOBAL oder LOAD_FAST sein (je nachdem, ob das Modul mit den Ausnahmen, global oder lokal) durch eine LOAD_ATTR gefolgt. Wenn es mehrere Ausnahmen angepasst wird, dann wird es eine Folge von Ladeoperationen durch einen BUILD_TUPLE (idiomatische) oder BUILD_LIST (einige andere seltsame oder nicht-idiomatische Situation).

gefolgt sein

Der Punkt ist, dass Sie durch die LOAD_X Anweisungen gehen und den Namen der Ausnahme, dass Sie passende vergleichen. Beachten Sie, dass Sie Name Vergleich nur . Wenn sie den Namen zugewiesen haben, sind Sie SOL.

Schritt 4: . Nehmen wir an, dass Sie eine Übereinstimmung gefunden. Nun müssen Sie die Funktion Objekt. Die beste Art und Weise, dass ich mich vorstellen kann, dies zu tun folgt (ich das Recht auf Updates reservieren): Die f.f_code ein co_filename Attribut hat. Sie können eine Schleife durch sys.modules und jeder wird __name__attribute haben. Sie können die beiden unter Berücksichtigung vergleichen, dass Sie __name__.endswith(co_filename) verwenden sollten. Wenn Sie ein Spiel bekommen, können Sie Schleife über die Module Funktionen und vergleichen ihre f.func_code.co_firstlineno Attribut mit dem Attribut Rahmen f.f_lineno. Wenn Sie ein Spiel erhalten, müssen Sie Ihre Funktion. Sie sollten auch in dem Modul jeder Klasse über die Methoden Schleife. Es gibt die Möglichkeit, dass die Behandlung in diesem Fall in irgendeiner verschachtelte Funktion auftritt, kann ich derzeit nicht denken Sie an eine vernünftige Sache zu tun. (Es wäre eine ganz andere Bytecode Hack und würde sich flockig sein)

Schritt 5 . Profit.

Das sollten Sie die allgemeine Vorstellung davon, wie über das tun dies zu gehen. Es gibt alle Arten von Ecke Fällen, in denen Sie in der Lage sein würden nicht, es zu tun, aber in jedem normalen Anwendungsfall sollten Sie in der Lage sein, um es auszuziehen. Wenn Sie Code schreiben, es hängt der Lage zu tun, auf sein, es brechen though. Dies ist eine Art von „Do it weil ich es kann“ Art der Sache.

Andere Tipps

Sie können nicht entscheiden, wo eine Ausnahme wird, ohne dass die Ausnahme tatsächlich behandelt bekommen zu erhöhen. Dies ist leicht zu sehen, hier:

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

Jede Funktion, die tut, was Sie würde haben wollen hier eine Benutzereingabe vorherzusagen. Das ganze Unternehmen ist zwecklos und Python hat keine Unterstützung für sie.

Wie auch immer, ich hoffe, Sie fragen nur aus Interesse ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top