File name and line number
Alex Martelli
aleaxit at yahoo.com
Fri Aug 10 15:31:14 EDT 2001
[Posted and mailed, as requested]
"Marielle Fois" <im99_foa at nada.kth.se> wrote in message
news:Pine.SOL.4.30.0108102017490.22519-100000 at my.nada.kth.se...
> Hello,
>
> Is is possible to know the name of a python file within the file
> itself? And the line number of the instruction that is currently
> being executed?
When a Python module is imported, Python sets its __file__
attribute to the filename of the file it was imported from.
If you're talking about a module rather than a main script,
this should suffice for your 'name of a python file' request.
Do note that the *directory* part of the name may differ
(you may use the functions in module os.path to normalize
and/or analize it, of course).
For more generality you need function _getframe of module
sys. As the leading _ indicates, it's a "delicate" function,
meant to be used only for very special purposes -- getting
filename and linenumber presumably meet the "very special"
test, being a typical task of a development/debugging
framework rather than of normal programs.
sys._getframe() returns the frame object it was called
from (you can get the caller's frame, the caller's caller's
frame, etc, by passing _getframe a numeric argument:
default is 0, 1 means caller's frame, and so on).
One of the attributes of a frame object is f_lineno, which
gets incremented (in a non-optimized Python run, only;
i.e., if Python was *NOT* started with option -O or -OO!)
by a special bytecode operation so it always reflects the
current linenumber in the execution frame. For example,
save the following to file lino.py:
import sys
x = sys._getframe()
print 'line',x.f_lineno
print 'line',x.f_lineno
print 'line',x.f_lineno
and run it:
D:\Python21>python lino.py
line 3
line 4
line 5
However, if you optimize, it's not that useful any more:
D:\Python21>python -O lino.py
line 1
line 1
line 1
but them's the breaks -- no line-numbers from optimized
bytecode (you only optimize when you're finished doing
development and debugging, anyway).
For the filename, add one last line to the above script:
print 'file',x.f_code.co_filename
and now running it you get:
D:\Python21>python lino.py
line 3
line 4
line 5
file lino.py
(the filename information remains even with -O).
> Suppose I have a function, and I want this function
> to take two arguments, first the name of the file where it is placed,
> and second at which line number. Is there any way of doing this?
This is a different question, of course -- you're asking not
what file is currently executing or on what line, but in what
file is a given function, and at what line (so you can pass
this info as arguments to the same function -- peculiar
but doable). If x is any reference to the function, e.g.
from amodule import afunction as x
or whatever, then:
x.func_code.co_filename is the filename,
x.func_code.co_firstlineno is the first line number
(i.e., the 'def' line).
So, calling:
x(x.func_code.co_filename,x.func_code.co_firstlineno)
should satisfy your peculiar request. By the way, this
is not affected by -O or -OO being in use.
Alex
More information about the Python-list
mailing list