getting the current function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gary Robinson

    getting the current function

    Alex Martelli has a cookbook recipe, whoami, for retrieving the name of the current function: http://aspn.activestate.com/ASPN/Coo...n/Recipe/66062. It uses sys._getframe() . I'm a little wary about using sys._getframe() because of the underscore prefix and the fact that the python docs say "This function should be used for internal and specialized purposes only."

    I feel more comfortable using the equivalent functionality in the inspect module.

    Also, I wanted a way to get access to the current function, not just its name.

    I came up with:

    import inspect

    def thisfunc(n=0):
    currentFrame = inspect.current frame()
    outerFrames = inspect.getoute rframes(current Frame)
    callingFrame = outerFrames[n + 1][0]
    callersCallingF rame = outerFrames[n + 2][0]
    return callersCallingF rame.f_locals[callingFrame.f_ code.co_name]

    The n argument lets you go up the stack to get callers of callers if that's convenient. For instance:

    def attr(name, value):
    caller = thisfunc(1)
    if not hasattr(caller, name):
    setattr(caller, name, value)

    def x():
    attr('counter', 0)
    thisfunc().coun ter += 1
    print thisfunc().coun ter

    x()
    x()
    x()

    Returns the output

    1
    2
    3

    Of course you don't need an attr() function for creating a function attribute, but this way your code won't break if you change the name of the function.

    I was about to create a cookbook recipe, but decided to ask for some feedback from the community first.

    Do you see situations where this function wouldn't work right?

    Also, the python docs warn about storing frame objects due to the possibility of reference cycles being created (http://docs.python.org/lib/inspect-stack.html). But I don't think that's a worry here since thisfunc() stores the references on the stack rather than the heap. But I'm not sure. Obviously, it would be easy to add a try/finally with appropriate del's, but I don't want to do it if it's not necessary.

    I welcome feedback of any type.

    Thanks,
    Gary




    --

    Gary Robinson
    CTO
    Emergent Music, LLC
    garyrob@mac.com
    207-942-3463
    Company: http://www.goombah.com
    Blog: http://www.garyrobinson.net
  • Jonathan Gardner

    #2
    Re: getting the current function

    On Sep 6, 8:43 am, Gary Robinson <gary...@mac.co mwrote:
    >
    I welcome feedback of any type.
    >
    This all seems a bit too complicated. Are you sure you want to do
    this? Maybe you need to step back and rethink your problem.

    Your example can be rewritten a number of different ways that are
    easier to think about.

    The simple approach:

    _x_counter = 0
    def x():
    _x_counter += 1
    return _x_counter

    The generator approach:

    def counter_gen():
    x = 0
    while True:
    x += 1
    yield x

    counter = counter_gen()
    counter.next()
    counter.next() # etc...

    A class-based approach:

    class Counter(object) :
    def __init__(self):
    self._x = 0

    def count(self):
    self._x += 1
    return self._x

    In general, there really isn't a need to mess with stack frames unless
    you are really interested in looking at the stack frame.

    Comment

    Working...