2013-01-19 17 views
8

Próbuję dowiedzieć się w czasie wykonywania, gdzie obiekt został utworzony, ponieważ umożliwiłoby to dostarczenie bardzo przydatnego komunikatu o błędzie użytkownikom mojej biblioteki.Jak mogę się dowiedzieć, gdzie utworzono obiekt?

Załóżmy, że mamy następujący kod:

import mylib 

obj = mylib.MyClass() 

obj jest następnie przekazywana do instancji innej klasy z mylib i przechodzi na wspaniałą podróż. Gdzieś wzdłuż linii, obj powoduje coś złego, i chciałbym wskazać użytkownikowi, gdzie utworzono instancję obj.

Miałem nadzieję, że będę mógł użyć modułu inspect, aby dowiedzieć się, w którym pliku i przy którym numerze linii obj został utworzony. Niestety, inspect.getsourcefile i inspect.getsourcelines nie obsługują instancji. Czy istnieje techniczny powód, dla którego nie jest to obsługiwane?

Czy istnieje inny sposób uzyskania danych, których szukam?

+0

czy to nie jest zbyt skomplikowane? kiedy dzieje się coś złego, dlaczego nie zrobić tego, co wszyscy (przypuszczalnie) robimy? W: import traceback + try: ... except: traceback.print_exc() – StefanNch

Odpowiedz

8

Można nagrać tę informację w klasie konstruktora jest:

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

Świetnie! Wiedziałem, że Python mnie nie zawiedzie. –

+0

Niestety nie działa to tak dobrze dla podklas, ponieważ każdy poziom dziedziczenia jest nową ramką stosu i może nie być stały dla każdego obiektu. W związku z tym może być wymagana dodatkowa logika określająca, ile ramek powrócić. Staje się to jeszcze bardziej skomplikowane w przypadku wielokrotnego dziedziczenia. – meowsqueak

0

może być chcesz to ??

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]: