2013-01-19 8 views
8

Sto cercando di scoprire, in fase di esecuzione, dove è stato istanziato un oggetto, in quanto ciò consentirebbe di fornire un messaggio di errore molto utile agli utenti della mia libreria.Come posso sapere dove è stato istanziato un oggetto?

Supponiamo di avere il seguente codice:

import mylib 

obj = mylib.MyClass() 

obj viene poi passato a un'istanza di un'altra classe da mylib, e procede in un viaggio meraviglioso. Da qualche parte lungo la linea, obj causa qualcosa di brutto, e vorrei indirizzare l'utente a dove obj è stato istanziato.

Speravo di poter utilizzare il modulo inspect per scoprire in quale file ea quale numero di riga obj è stato istanziato. Sfortunatamente, lo inspect.getsourcefile e inspect.getsourcelines non supportano le istanze. C'è una ragione tecnica per cui questo non è supportato?

C'è un altro modo per ottenere i dati che sto cercando?

+0

non è eccessivamente complicato? quando succede qualcosa di brutto, perché non fare ciò che tutti (presumibilmente) facciamo? Come in: import traceback + try: ... eccetto: traceback.print_exc() – StefanNch

risposta

8

Si potrebbe registrare tali informazioni nel costruttore della classe:

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

Eccellente! Sapevo che Python non mi avrebbe deluso. –

+0

Sfortunatamente questo non funziona molto bene per le sottoclassi, poiché ogni livello di ereditarietà è un nuovo stack frame e potrebbe non essere costante per ogni oggetto interessato. Quindi qualche logica in più per determinare quanti fotogrammi possono essere richiesti. Ciò diventa ancora più complicato quando sono coinvolte più eredità. – meowsqueak

0

potrebbe essere si desidera che questo ??

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