Traceback Funktionsaufruf: wer hat die Funktion aufgerufen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Nergal
User
Beiträge: 72
Registriert: Montag 6. Oktober 2008, 14:02

Donnerstag 2. April 2009, 10:42

Hallo,

ich suche eine Möglichkeit, mit der ich innerhalb einer Methode/Funktion abfragen kann, welches Modul (noch besser welche Methode/Funktion) sie aufgerufen hat?

Beispiel
Ich habe zwei Funktionen: ModulA.Fx und ModulB.Fy

Ich ruf von Fx die Funktion Fy aus ModulB auf. Nun möchte ich in Fy wissen, daß der Aufruf von ModulA bzw. Funktion Fx kam.

Ich möchte mitloggen, wer und wann eine Funktion aufgerufen wurde und möchte diese Information nicht bei jedem Aufruf mitgeben (zuviele Änderungen in bestehendem Quellcode).

Gibt es so eine Möglichkeit, oder muss ich mir etwas anderes einfallen lassen?

Gruß
Nergal
Zuletzt geändert von Nergal am Donnerstag 2. April 2009, 13:00, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Donnerstag 2. April 2009, 11:22

Das traceback-Modul ist dein Freund.
Das Leben ist wie ein Tennisball.
Nergal
User
Beiträge: 72
Registriert: Montag 6. Oktober 2008, 14:02

Donnerstag 2. April 2009, 12:38

Um zu sehen ob es funktioniert, habe ich folgendes in einer Methode eingebaut:

Code: Alles auswählen

        import traceback
        import sys
        tb = sys.exc_info()[2]
        print tb
        traceback.format_tb(tb)
Der Output ist allerdings jedes Mal

Code: Alles auswählen

<traceback object at 0x011AD788>
None
Habe es auch mit sys.last_traceback probiert, allerdings bekomme ich dann den Fehler, daß das Modul kein Attribut last_traceback hat.

Momentan steh ich voll auf'm Schlauch.


Gruß
Nergal
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Donnerstag 2. April 2009, 13:38

Ich nehme mal an, daß du

Code: Alles auswählen

print traceback.print_stack(tb)
oder sowas in der Art suchst. Läßt sich sicherlich auch noch aufhübschen. Um bei deinem Beispiel zu bleiben: Für ein TraceBack-Objekt ist offensichtlich keine __repr__ oder ähnliches definiert, weshalb 'print tb' nicht so viel Sinn macht. Bei deiner letzten Zeile geht die Ausgabe einfach verloren, weil das 'print' davor fehlt.
Benutzeravatar
snafu
User
Beiträge: 5440
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Donnerstag 2. April 2009, 17:08

Aber der Traceback kommt doch nur bei einem Fehler (Exeption), oder nicht? Wie ich ihn verstehe, will er generell wissen, von wo aus eine Funktion aufgerufen wurde.
shcol (Repo | Doc | PyPi)
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Donnerstag 2. April 2009, 17:35

snafu hat geschrieben:Aber der Traceback kommt doch nur bei einem Fehler (Exeption), oder nicht? Wie ich ihn verstehe, will er generell wissen, von wo aus eine Funktion aufgerufen wurde.
Nö, dann wird er nur ausgegeben. Der Callstack wird immer mitgeführt, sonst wüsste der Interpreter nicht, wohin er nach einer Funktion zurückspringen sollte. Mit dem traceback-Modul kommt man da jeder Zeit ran.
Das Leben ist wie ein Tennisball.
Nergal
User
Beiträge: 72
Registriert: Montag 6. Oktober 2008, 14:02

Freitag 3. April 2009, 08:20

Muss mich damit am Wochenende mal genauer auseinander setzen.

Im Moment bekomme ich immer nur None ausgegeben, was snafu's Überlegung unterstützen würde :/

Gruß
Nergal
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Freitag 3. April 2009, 09:21

Also ich benkomme vernünftige Ergebnisse:

Code: Alles auswählen

traceback.extract_stack()
Das Leben ist wie ein Tennisball.
Benutzeravatar
snafu
User
Beiträge: 5440
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Freitag 3. April 2009, 09:27

Also Galileo Computing definiert "Traceback" so:
Ein Traceback-Objekt hält den Kontext fest, aus dem eine Exception geworfen wurde, und liefert damit die Informationen, die bei einem Traceback auf dem Bildschirm angezeigt werden. Zu diesen Informationen gehört vor allem die Funktionshierarchie, der sogenannte Callstack. Ein Traceback-Objekt wird beim Werfen einer Exception automatisch erzeugt.
Quelle

Ich weiß allerdings nicht, wieviel Wert man dieser Aussage beimessen kann, da das Buch hier von vielen als "problematisch" (milde gesagt) angesehen wird.

Aber auch die Doku zu [mod]traceback[/mod] sagt ja:
The module uses traceback objects — this is the object type that is stored in the variables sys.exc_traceback (deprecated) and sys.last_traceback and returned as the third item from sys.exc_info().
Folglich käme man an ein `traceback`-Objekt und damit an den Stack nur dann, wenn eine Exception geworfen wird. Das scheint mir aber wie gesagt nicht im Sinne des OP's zu sein...

Und auch zu sys.last_traceback:
[...] set when an exception is not handled and the interpreter prints an error message
...und eben nicht grundsätzlich nach jedem Aufruf einer Funktion/Klasse/usw.
shcol (Repo | Doc | PyPi)
lunar

Freitag 3. April 2009, 09:50

Du könntest – anstatt wilde Vermutungen anzustellen – ja mal die letzten beiden Beispiele in der traceback-Doku lesen oder einfach den Interpreter anwerfen :roll:
Antworten