Terry Carroll wrote: > On Tue, 17 May 2005, Kent Johnson wrote: > > >>I often find that the information in the traceback and exception are >>enough to figure out the problem; if not, a few print statements can >>help. You will get better at this with experience. > > > Here's an example where traceback and print statements doesn't help, and > it's really nice to have access to the variables... > > Suppose I have a long list of lists (by "long," I mean, too long to > display on one screen and visually examine easily), and am iterating over > the inner lists. (Forget whether there might be more > efficient ways; > this is just for illustration.) > > In most languages, you'd take this unpythonic approach: > > for i in range(0,len(mylist)): > for j in range(0, len(mylist[i])): > # stuff dependent on mylist[i][j] > > I could put in "print i,j, mylist[i][j]" statements in here, and pretty > easily zero in on the exceptional data. > > But a pythonic approach, and the one I find easiest, is: > > for innerlist in mylist: > for item in innerlist: > # stuff dependent on item > > Now, I can only put in "print item", and finding that in the nested list > is like a needle in a haystack. That's what I like about the -i > option... I can use Python expressions to iterate through the list > lookingfor stuff. > > Is there any way, in the second construct, to have the traceback (or > equivalent info) include where in "innerlist" "item" came from, and where > in "mylist" "innerlist" came from?
OK, you have prompted me to play around with the recipe I cited earlier. Here is a version that looks promising to me. I have this in Python24\Lib\site-packages\debug_helper.py: ### import sys, traceback def print_exc_plus_hook(type, value, tb): """ Print the usual traceback information, followed by a listing of all the local variables in the current frame. Based on this recipe: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52215 """ if not tb or issubclass(type, SyntaxError): sys.__excepthook__(type, value, tb) return traceback.print_exception(type, value, tb) while 1: if not tb.tb_next: break tb = tb.tb_next frame = tb.tb_frame # Try to filter out top-level command line errors if frame.f_locals.has_key('__builtins__'): return print >> sys.stderr print >> sys.stderr, "Frame %s in %s at line %s" % (frame.f_code.co_name, frame.f_code.co_filename, frame.f_lineno) for key, value in frame.f_locals.items(): print >> sys.stderr, "\t%20s = " % key, #We have to be careful not to cause a new error in our error #printer! Calling repr() on an unknown object could cause an #error we don't want. try: print >> sys.stderr, repr(value) except: print >> sys.stderr, "<ERROR WHILE PRINTING VALUE>" def install_excepthook(): sys.excepthook = print_exc_plus_hook ### Then I created a file Python24\Lib\site-packages\sitecustomize.py containing these few lines: # Install an exception handler that prints the current stack frame from debug_helper import install_excepthook install_excepthook() ### Now when I get an exception the usual stack trace prints plus the values of the local variables. (I took out the printing of the variables in the higher stack frames, that seems like overkill to me. So in your example, when an exception occurs, you would get a printout with the values of innerlist and item which are both variables in the local scope. If you want more, you could temporarily change the list to for i, innerlist in enumerate(mylist): for j, item in enumerate(innerlist): # stuff dependent on item then you will get the indices as well. I'm going to try this out and see I find it helpful... Kent _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor