Elf M. Sternberg elfs



C __LINE__ equivalent in Python I started using this recently. If you do a lot of Python, you’ll sometimes find yourself desperate for breadcrumbs, little print statements scattered throughout your code as you try to figure what you told it to do, since it’s obviously not doing what you want it to do. I’d used inspect previously to unravel exception handlers; there’s a customized one inside the Isilon UI, so if the product fails in the field the exception will be logged to a file for later analysis, but this is a nice little routine. It’s basically a pythonic version of the C __LINE__ macro. Wherever you think you might need a debugging statement, put if DEBUG: print _line(), foo, bar, baz and you’ll not only get the fields you want to see, but also the name of the function/method, and the line number of the print statement. import inspect def _line(): info = inspect.getframeinfo(inspect.currentframe().f_back)[0:3] return '[%s:%d]' % (info[2], info[1]) Use as needed. This entry was automatically cross-posted from Elf's technical journal, ElfSternberg.com Tags: programming, python

From: tamino Date: September 24th, 2008 12:39 am (UTC) (Link) Even simpler:



def _line():

f = sys._getframe().f_back

return '[%s:%d]' % (f.f_code.co_filename, f.f_lineno) From: elfs Date: September 24th, 2008 05:17 am (UTC) (Link) I thought f_lineno gave you the first line of the current method, not the current line. From: tamino Date: September 24th, 2008 05:26 am (UTC) (Link) Nope -- if you look at what inspect.getframeinfo is doing, it's getting it from f_lineno (as well as doing a bunch of other work to assemble information that you're discarding, and the gathering of which will slow things down)



You may be thinking of the f_lineno member of the python frame struct in C. You're right that that doesn't get updated on every line, but if you access it from within python, yes, it'll make sure it's up to date before it returns the value to you.



Incidentally, in gdb, where you *do* have to worry about these issues, I use:



p (char *)(((PyStringObject *)f->f_code->co_filename)->ob_sval)

p PyCode_Addr2Line(f->f_code, f->f_lasti)



the latter of which does the actual magic to get the correct line number (f->f_lineno will likely be out of date).