étale-cohomology
étale-cohomology

Reputation: 1861

Function to return the function name and line

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

Answers (1)

freshpasta
freshpasta

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

Second way:

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

Related Questions