0
def f(): return g=f 

g.func_name is "f"

How do I get "g"?

3
  • 1
    Independently of wether there is or isn't a solution, why do you need this in the first place? Commented Apr 3, 2012 at 19:56
  • 1
    Short answer: you can't. Commented Apr 3, 2012 at 19:56
  • 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) Commented Apr 3, 2012 at 20:58

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Nice answer, except that it isn't really a correct answer. You actually can. Whether you should is a different matter ;-)
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.
"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 ;-)
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'] 

1 Comment

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.
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.

Comments

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'] 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.