Reputation: 1861
You can get the function name and line with sys._getframe().f_code.co_name
and sys._getframe().f_lineno
.
I'd like a wrapper around these (awkward) values, something like:
def fn(): return sys._getframe().f_code.co_name
def line(): return sys._getframe().f_lineno
but that doesn't work.
For example, the following code
import sys
def fn(): return sys._getframe().f_code.co_name
def line(): return sys._getframe().f_lineno
def main():
print(sys._getframe().f_code.co_name, fn())
print(sys._getframe().f_lineno, line())
main()
should return
main main
8 8
but instead it returns
main fn
8 4
How can I achieve the desired effect?
Upvotes: 1
Views: 351
Reputation: 616
EDIT: Turns out you can do it just relying on sys
, by passing parameter 1
to sys._getframe
to get the frame below the current one fn
. According to python documentation:
sys._getframe([depth])
Return a frame object from the call stack. If optional integer depth is given, return the frame object that many calls below the top of the stack. If that is deeper than the call stack, ValueError is raised. The default for depth is zero, returning the frame at the top of the call stack.
Your code will look like this:
import sys
def fn(): return sys._getframe(1).f_code.co_name
def line(): return sys._getframe(1).f_lineno
def main():
print(sys._getframe().f_code.co_name, fn())
print(sys._getframe().f_lineno, line())
main()
Output
main main
8 8
sys._getframe().f_code.co_name
will return the current function, which is always fn
. To get the frame below the current one, use traceback
:
import sys
import inspect
def fn(): return inspect.stack()[-2].function
def line(): return inspect.stack()[-2].lineno
def main():
print(sys._getframe().f_code.co_name, fn())
print(sys._getframe().f_lineno, line())
main()
Output
main main
9 9
Upvotes: 1