2

A small bit of code will explain why I'm asking and why this is not a duplicate. (I hope)

>>> def foo():
...    return 1
... 
>>> bar=foo
>>> bar.__name__
'foo'

How do I get 'bar'?

I've tried inspect and frames, but everything I've found so far fails this test.

6
  • 6
    you can't, bar is just a reference to foo. Commented Jan 25, 2013 at 0:29
  • What's wrong with 'bar'? You have to write name anyway. Commented Jan 25, 2013 at 0:34
  • The odd part isn't that you can't get 'bar' it's that you don't get both names or none at all. Commented Jan 25, 2013 at 0:36
  • @PeterWooster Python saves the function name on declaration. As Ashwini Chaudhary said, bar is just a reference to the same function, which has a single name (which is the one it was declared as) Commented Jan 25, 2013 at 0:43
  • 3
    BTW: if you step back and tell us about why you want the name of bar, we can help you find a solution. Commented Jan 25, 2013 at 0:46

4 Answers 4

2

bar is just a reference to an already created object(foo), doing bar=foo means you created another reference to the same object.

In [62]: def foo():pass

In [63]: bar=foo

In [64]: spam=bar     #another reference to foo function object

In [65]: spam.__name__,bar.__name__
Out[65]: ('foo', 'foo')

In [66]: spam is foo,bar is foo
Out[66]: (True, True)

In [67]: import sys

In [68]: sys.getrefcount(foo)  # no of variable pointing to that object

Out[68]: 4           #3+1, 1 added by default by getrefcount()
Sign up to request clarification or add additional context in comments.

Comments

1

After you assign bar = foo, you have two names that both refer to the exact same value. There's no way in Python to distinguish between them. Assignment in Python never copies data, it just makes a name refer to a value, and a function is a value like any other. There is only one function, and it has only one __name__.

Comments

0

If you know foo then you can check globals() to see if other functions are assigned to that function, note that this will pick up all other references:

>>> function_reference_names  = [k for k, v in globals().iteritems() if hasattr(globals()[k], "func_name") and globals()[k].func_name == bar.__name__ and k != bar.__name__]
>>> function_reference_names
['bar']

But as others have pointed out, if you want to do this, your probably asking the wrong question.

1 Comment

This code looks for other functions named foo. You can define as many "foo" functions as you like, so it isn't clear this is what the OP wanted.
0

Well it's an interesting question, can a function know what name it's called by? As far as I know, this piece of information is not stored in the stack or anywhere else, so to fetch it, we'll have to go into higher dimensions, or go meta, to manipulate the info of the source itself.

The result may not be useful, but it's funny :)

Below is the clumsy code:

import inspect
import io
import re

def get_my_name(func_obj):
    caller_frame = inspect.currentframe().f_back.f_back
    caller_mod = inspect.getmodule(caller_frame)
    mod_src = inspect.getsource(caller_mod)
    call_lineno = caller_frame.f_lineno

    stream = io.StringIO(mod_src)
    for i in range(0, call_lineno):
        line = stream.readline()
    m = re.findall('[_a-zA-Z0-9]+(?=\()', line)
    m = [fname for fname in m if caller_frame.f_locals[fname] == func_obj]
    return m

def some_func(n):
    print(get_my_name(some_func))
    return n*n

def caller():
    f = some_func
    return f(2)

caller()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.