Determine which function was called

Go To StackoverFlow.com

0

def f():
   return


g=f

g.func_name is "f"

How do I get "g"?

2012-04-03 19:53
by user1308523
Independently of wether there is or isn't a solution, why do you need this in the first place - SingleNegationElimination 2012-04-03 19:56
Short answer: you can't - Cat Plus Plus 2012-04-03 19:56
I also think you can' - pylover 2012-04-03 20:00
Also in the case of lambdas, they will have no name except '<lambda>'. (Lambdas share types with normal functions, at least in CPython: types.FunctionType==types.LambdaType - ninjagecko 2012-04-03 20:58


6

You can't.

EDIT: gc.get_referrers exists, but will not tell you which reference to a function object was used to call it, so it doesn't help you. In addition, there are certain caveats when using that function and I don't know whether it works under implementations other than CPython. Its use in production code is discouraged.

As a final note, while the FAQ may not be entirely correct about whether you can determine an object's name, its insights as to whether you should are dead-on.

2012-04-03 19:57
by Taymon
(See the link for a very good explanation. - Taymon 2012-04-03 20:01
Nice answer, except that it isn't really a correct answer. You actually can. Whether you should is a different matter ;- - Raymond Hettinger 2012-04-03 20:08
Re-edited answer to reflect this. I didn't know about gc.get_referrers, but I think you still can't tell which reference to a function was used to call it - Taymon 2012-04-03 20:49
"Can't" is a dangerous word to use when talking about Python ;-) Take a look at sys._getframe and think about how tracing, profiling, and pdb work. Python has A LOT of ways to do introspection. Accordlingly, you should be hesitant to use the word CAN'T when talking about a CAN DO language like Python. Just say-in ;- - Raymond Hettinger 2012-04-04 01:00


2

When f is created by def, the __name__ attributed is created at the same time. That attribute is assigned to the function object and it persists no matter what you subsequently assign the function to.

In general, an object doesn't know which variables it points to.

However, we do have tools like gc.get_referrers() than use implementation specific logic to find all the references to an object:

>>> def f(x):
    return x**2

>>> g = f

>>> import gc
>>> gc.get_referrers(f)[0].keys()
['g', 'f', '__builtins__', '__package__', 'gc', '__name__', '__doc__']

Another technique is to scan a namespace for all instances of a particular object:

>>> [key for key, value in globals().items() if value == f]
['g', 'f']
2012-04-03 20:01
by Raymond Hettinger
That finds all the names for the function, rather than "find under what name a function was called" as stated in the question title (or am I missing something?). May still be useful for the OP, of course - weronika 2012-04-03 20:28


1

You may be able to do it by inspecting the source code using inspect module, and only then with some limitations (at the very least, you'll need to be able to obtain the line where the name in question is mentioned).

You absolutely shouldn't do that unless you really know why you need it.

2012-04-03 20:02
by max


1

a = 1
b = 1
c = 1

What is the name of 1? Does that question even make sense?

A function is an object like any other, such as 1 or "cats". It has a __name__ attribute that tells you what name it was originally defined as, but other names can be assigned to it, and no record is kept on the object of these assignments.

You can search all local and global variables for it, but this won't find every possible reference; references to the function can be held in containers such as dictionaries or lists, as object attributes, as globals in other modules, and probably other places I'm not thinking of right now. Oh! Closures. Still, this is the gist:

def f():
    pass

g = f

allvars = dict(globals())
allvars.update(locals())
funcnames = [key for (key, value) in allvars.iteritems() if value is f]
# returns ['g', 'f']
2012-04-03 20:04
by kindall