Wednesday, March 13, 2013

Python one-liner to get the filename and line number of the caller of the current function

By Vasudev Ram

Just saw this:

An ActiveState Python recipe to get the filename and line number of the calling function.

I modified it and tried it out, while I happened to be at an Internet cafe, using Portable Python, which I had blogged about earlier.

Here is my modified code:
# caller_info.py

import sys

def foo():
 print "in foo"
 f1 = sys._getframe(1)
 f2 = sys._getframe(2)
 print "f1: filename, lineno:", f1.f_code.co_filename, f1.f_lineno
 print "f2: filename, lineno:", f2.f_code.co_filename, f2.f_lineno

def bar():
 print "in bar"
 print "calling foo"
 foo()

bar()

And here is the output of "running" (*) that file, caller_info.py, using Portable Python:

>>> import caller_info
in bar
calling foo
in foo
f1: filename, lineno: caller_info.py 16
f2: filename, lineno: caller_info.py 18
>>>
(*) I said "running" because, as you can see from the code, I had to use a roundabout method of running the caller_info.py file with PortablePython. The standard method, like "python caller_info.py", that normal Python supports, does not seem to work with PortablePython (at least on a quick check or two; there may be some other way that works, such as a command-line switch or whatever). So I resorted to importing the file and letting the code in it run as a side-effect. Anyway, it seems to show that the one-liner works, because in the output shown, the filename is right, and so are the line numbers of the calls to foo and bar - I checked in the editor that the numbers are 16 and 18.

Just for fun, I also tried the same code (not as a Python file, just typed in), in the
repl.it online pastebin that I blogged about earlier. It worked, sort of, the line number shown was 1 and the filename shown was stdin:
def foo(): 
..   print "in foo" 
..
 def bar(): 
..   print "in bar, calling foo" 
..   foo() 
..   f = sys._getframe(1) 
..   print f.f_code.co_filename 
..   print f.f_lineno 
..   
   bar()
in bar, calling foo
in foo
<stdin>
1
- Vasudev Ram - Dancing Bison Enterprises


No comments: