G
Gary Robinson
Alex Martelli has a cookbook recipe, whoami, for retrieving the name of the current function: http://aspn.activestate.com/ASPN/Cookbook/Python/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
(e-mail address removed)
207-942-3463
Company: http://www.goombah.com
Blog: http://www.garyrobinson.net
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
(e-mail address removed)
207-942-3463
Company: http://www.goombah.com
Blog: http://www.garyrobinson.net