471,330 Members | 1,767 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,330 software developers and data experts.

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.currentframe()
outerFrames = inspect.getouterframes(currentFrame)
callingFrame = outerFrames[n + 1][0]
callersCallingFrame = outerFrames[n + 2][0]
return callersCallingFrame.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().counter += 1
print thisfunc().counter

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
ga*****@mac.com
207-942-3463
Company: http://www.goombah.com
Blog: http://www.garyrobinson.net
Sep 6 '07 #1
1 2668
On Sep 6, 8:43 am, Gary Robinson <gary...@mac.comwrote:
>
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.

Sep 6 '07 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

303 posts views Thread by mike420 | last post: by
3 posts views Thread by Beryl Small | last post: by
11 posts views Thread by KarimL | last post: by
11 posts views Thread by singlal | last post: by
1 post views Thread by John Wilhelm | last post: by
1 post views Thread by pukya78 | last post: by
30 posts views Thread by Ashit Vora | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.