2013-01-19 5 views
8

Ich versuche, zur Laufzeit herauszufinden, wo ein Objekt instanziiert wurde, da dies eine sehr nützliche Fehlermeldung für Benutzer meiner Bibliothek bereitstellen würde.Wie kann ich herausfinden, wo ein Objekt instanziiert wurde?

Angenommen, wir den folgenden Code haben:

import mylib 

obj = mylib.MyClass() 

obj wird dann auf eine Instanz einer anderen Klasse übergeben von mylib und geht auf eine wunderbare Reise. Irgendwo entlang der Linie, verursacht obj etwas schlechtes, und ich möchte den Benutzer darauf verweisen, wo obj instanziiert wurde.

Ich hatte gehofft, ich könnte das inspect Modul verwenden, um herauszufinden, in welcher Datei und bei welcher Zeilennummer obj instanziiert wurde. Leider unterstützen die inspect.getsourcefile und inspect.getsourcelines Instanzen nicht. Gibt es einen technischen Grund, warum dies nicht unterstützt wird?

Gibt es eine andere Möglichkeit, die gesuchten Daten zu erhalten?

+0

ist das nicht zu kompliziert? Wenn etwas Schlimmes passiert, warum tust du nicht das, was wir alle (vermutlich) tun? Wie in: traceback importieren + try: ... außer: traceback.print_exc() – StefanNch

Antwort

8

Sie können diese Informationen in Ihrer Klasse Konstruktor auf:

import traceback 

class MyClass(object): 
    def __init__(self): 
     self.traceback = traceback.extract_stack()[-2] 

obj = MyClass() 

print 'Instantiated in {0}:{1}'.format(*obj.traceback) 
+0

Excellent! Ich wusste, dass Python mich nicht enttäuschen würde. –

+0

Leider funktioniert dies nicht so gut für Unterklassen, da jede Vererbungsebene ein neuer Stapelrahmen ist und nicht für jedes betroffene Objekt konstant sein kann. Also einige zusätzliche Logik, um festzustellen, wie viele Frames zurückgehen kann erforderlich sein. Dies wird noch komplizierter, wenn Mehrfachvererbung beteiligt ist. – meowsqueak

0

können Sie dies wollen ??

In [1]: def checkinstance(prohibitedclass): 
    ...:  import sys 
    ...:  final_result=set() 
    ...:  for x in sys._getframe(1).f_locals: 
    ...:   if isinstance(sys._getframe(1).f_locals.get(x),prohibitedclass): 
    ...:    final_str="instance of class %s is at: %s"%(prohibitedclass,sys._getframe(1).f_locals.get(x)) 
    ...:    final_result.add(final_str) 
    ...:  return list(final_result) 

In [2]: class not_allowedclass(object): 
    ...:  pass 

In [3]: checkinstance(not_allowedclass) 
Out[3]: [] 

In [4]: nk=not_allowedclass() 

In [5]: nk1=not_allowedclass() 

In [6]: checkinstance(not_allowedclass) 
Out[6]: 
["instance of class <class '__main__.not_allowedclass'> is at: <__main__.not_allowedclass object at 0x102dcdb10>", 
"instance of class <class '__main__.not_allowedclass'> is at: <__main__.not_allowedclass object at 0x102dcda90>"] 

In [7]: nk 
Out[7]: <__main__.not_allowedclass at 0x102dcda90> 

In [8]: nk1 
Out[8]: <__main__.not_allowedclass at 0x102dcdb10> 

In [9]: