Finding the name of a function while defining it

Discussion in 'Python' started by Abhas Bhattacharya, Dec 26, 2012.

  1. While I am defining a function, how can I access the name (separately as string as well as object) of the function without explicitly naming it(hard-coding the name)?
    For eg. I am writing like:
    def abc():
    #how do i access the function abc here without hard-coding the name?
     
    Abhas Bhattacharya, Dec 26, 2012
    #1
    1. Advertising

  2. Abhas Bhattacharya

    Roy Smith Guest

    In article <>,
    Abhas Bhattacharya <> wrote:

    > While I am defining a function, how can I access the name (separately as
    > string as well as object) of the function without explicitly naming
    > it(hard-coding the name)?
    > For eg. I am writing like:
    > def abc():
    > #how do i access the function abc here without hard-coding the name?


    Do you need it at compile-time, or is it good enough to have the name a
    run-time? Assuming the latter, then I'm thinking the traceback module
    is your friend. Call traceback.extract_stack() and pull off the last
    frame in the stack. The function name will be in there.

    There may be a cleaner way, but that's what I've done in the past.

    I've only ever wanted the name. If you need the actual function object,
    I suppose you might eval() the name, or something like that.
     
    Roy Smith, Dec 26, 2012
    #2
    1. Advertising

  3. On Thu, Dec 27, 2012 at 3:52 PM, Tim Roberts <> wrote:
    > The
    > compiled code in a function, for example, exists as an object without a
    > name. That unnamed object can be bound to one or more function names, but
    > the code doesn't know that. Example:
    >
    > def one():
    > print( "Here's one" )
    >
    > two = one
    >
    > That creates one function object, bound to two names. What name would you
    > expect to grab inside the function?


    Presumably 'one'.

    > Even more obscure:
    >
    > two = lamba : "one"
    > one = two
    >
    > Which one of these is the "name" of the function?


    I would say '<lambda>'. Whatever method is used to get the function's
    name, I would expect it to match the __name__ attribute of the
    function (which is a peer to __code__, but I don't think the
    function's code *is* the function).

    ChrisA
     
    Chris Angelico, Dec 27, 2012
    #3
  4. On Wednesday, 26 December 2012 08:41:28 UTC+5:30, Roy Smith wrote:
    > In article <>,
    >
    > Abhas Bhattacharya <> wrote:
    >
    >
    >
    > > While I am defining a function, how can I access the name (separately as

    >
    > > string as well as object) of the function without explicitly naming

    >
    > > it(hard-coding the name)?

    >
    > > For eg. I am writing like:

    >
    > > def abc():

    >
    > > #how do i access the function abc here without hard-coding the name?

    >
    >
    >
    > Do you need it at compile-time, or is it good enough to have the name a
    >
    > run-time? Assuming the latter, then I'm thinking the traceback module
    >
    > is your friend. Call traceback.extract_stack() and pull off the last
    >
    > frame in the stack. The function name will be in there.
    >
    >
    >
    > There may be a cleaner way, but that's what I've done in the past.
    >
    >
    >
    > I've only ever wanted the name. If you need the actual function object,
    >
    > I suppose you might eval() the name, or something like that.


    I need it compile-time.
    During run-time, I can always use: function_name.__name__ (although that's kind of lame because it returns "function_name"). But if the function itself contains print(__name__) and I call the function, it returns __main__ (yes, __main__ itself, not the string "__main__") (which is the calling function).
     
    Abhas Bhattacharya, Dec 27, 2012
    #4
  5. On Thursday, 27 December 2012 10:22:15 UTC+5:30, Tim Roberts wrote:
    > Abhas Bhattacharya <> wrote:
    >
    > >

    >
    > >While I am defining a function, how can I access the name (separately as

    >
    > >string as well as object) of the function without explicitly naming

    >
    > >it(hard-coding the name)?

    >
    > >For eg. I am writing like:

    >
    > >def abc():

    >
    > > #how do i access the function abc here without hard-coding the name?

    >
    >
    >
    > Why? Of what value would that be?
    >
    >
    >
    > Note that I'm not merely being obstructionist here. What you're asking
    >
    > here is not something that a Python programmer would normally ask. The
    >
    > compiled code in a function, for example, exists as an object without a
    >
    > name. That unnamed object can be bound to one or more function names, but
    >
    > the code doesn't know that. Example:
    >
    >
    >
    > def one():
    >
    > print( "Here's one" )
    >
    >
    >
    > two = one
    >
    >
    >
    > That creates one function object, bound to two names. What name would you
    >
    > expect to grab inside the function?
    >
    >
    >
    > Even more obscure:
    >
    >
    >
    > two = lamba : "one"
    >
    > one = two
    >
    >
    >
    > Which one of these is the "name" of the function?
    >
    > --
    >
    > Tim Roberts,
    >
    > Providenza & Boekelheide, Inc.


    It is of quite value to me.
    Because I have this situation:
    I have used a dictionary with "function_name":value pair in the top of the code. Now when some function is called, I need to print the value assigned to its name in the dictionary (the functions are defined after the dictionary). Now there is only one bad way-around for me: I need to hard-code the name in the function like this:
    def function_name():
    print(dict_name.get("function_name"))
    but ofcourse it is a bad thing to do because I have a lot of this type of functions. It would be better if I can can use the same code for all of them, because they are all essentially doing the same thing.

    Now, for your questions:
    If i call one() and two() respectively, i would like to see "one" and "two"..
    I dont have much knowledge of lambda functions, neither am i going to use them, so that's something I cant answer.
     
    Abhas Bhattacharya, Dec 27, 2012
    #5
  6. On Thursday, 27 December 2012 11:14:36 UTC+5:30, Chris Angelico wrote:
    > On Thu, Dec 27, 2012 at 3:52 PM, Tim Roberts <> wrote:
    >
    > > The

    >
    > > compiled code in a function, for example, exists as an object without a

    >
    > > name. That unnamed object can be bound to one or more function names, but

    >
    > > the code doesn't know that. Example:

    >
    > >

    >
    > > def one():

    >
    > > print( "Here's one" )

    >
    > >

    >
    > > two = one

    >
    > >

    >
    > > That creates one function object, bound to two names. What name would you

    >
    > > expect to grab inside the function?

    >
    >
    >
    > Presumably 'one'.
    >
    >
    >
    > > Even more obscure:

    >
    > >

    >
    > > two = lamba : "one"

    >
    > > one = two

    >
    > >

    >
    > > Which one of these is the "name" of the function?

    >
    >
    >
    > I would say '<lambda>'. Whatever method is used to get the function's
    >
    > name, I would expect it to match the __name__ attribute of the
    >
    > function (which is a peer to __code__, but I don't think the
    >
    > function's code *is* the function).
    >
    >
    >
    > ChrisA


    If i call one() and two() respectively, i would like to see "one" and "two".
     
    Abhas Bhattacharya, Dec 27, 2012
    #6
  7. On Thursday, 27 December 2012 11:14:36 UTC+5:30, Chris Angelico wrote:
    > On Thu, Dec 27, 2012 at 3:52 PM, Tim Roberts <> wrote:
    >
    > > The

    >
    > > compiled code in a function, for example, exists as an object without a

    >
    > > name. That unnamed object can be bound to one or more function names, but

    >
    > > the code doesn't know that. Example:

    >
    > >

    >
    > > def one():

    >
    > > print( "Here's one" )

    >
    > >

    >
    > > two = one

    >
    > >

    >
    > > That creates one function object, bound to two names. What name would you

    >
    > > expect to grab inside the function?

    >
    >
    >
    > Presumably 'one'.
    >
    >
    >
    > > Even more obscure:

    >
    > >

    >
    > > two = lamba : "one"

    >
    > > one = two

    >
    > >

    >
    > > Which one of these is the "name" of the function?

    >
    >
    >
    > I would say '<lambda>'. Whatever method is used to get the function's
    >
    > name, I would expect it to match the __name__ attribute of the
    >
    > function (which is a peer to __code__, but I don't think the
    >
    > function's code *is* the function).
    >
    >
    >
    > ChrisA


    If i call one() and two() respectively, i would like to see "one" and "two".
     
    Abhas Bhattacharya, Dec 27, 2012
    #7
  8. On Thu, Dec 27, 2012 at 6:26 PM, Abhas Bhattacharya
    <> wrote:
    > During run-time, I can always use: function_name.__name__ (although that's kind of lame because it returns "function_name"). But if the function itself contains print(__name__) and I call the function, it returns __main__ (yes, __main__ itself, not the string "__main__") (which is the calling function).


    That's because __name__ looks for that attribute on the module (aka
    "global variable"), not the function. When you run your Python script
    as an application, the module is called __main__.

    ChrisA
     
    Chris Angelico, Dec 27, 2012
    #8
  9. On Thursday, 27 December 2012 13:18:19 UTC+5:30, Chris Angelico wrote:
    > On Thu, Dec 27, 2012 at 6:26 PM, Abhas Bhattacharya
    >
    > <> wrote:
    >
    > > During run-time, I can always use: function_name.__name__ (although that's kind of lame because it returns "function_name"). But if the function itself contains print(__name__) and I call the function, it returns __main__(yes, __main__ itself, not the string "__main__") (which is the calling function).

    >
    >
    >
    > That's because __name__ looks for that attribute on the module (aka
    >
    > "global variable"), not the function. When you run your Python script
    >
    > as an application, the module is called __main__.
    >
    >
    >
    > ChrisA


    Ok, that sheds some light on why it acts like that, but how can i use it the way I want (which i already told)?
     
    Abhas Bhattacharya, Dec 27, 2012
    #9
  10. On Thursday, 27 December 2012 13:18:19 UTC+5:30, Chris Angelico wrote:
    > On Thu, Dec 27, 2012 at 6:26 PM, Abhas Bhattacharya
    >
    > <> wrote:
    >
    > > During run-time, I can always use: function_name.__name__ (although that's kind of lame because it returns "function_name"). But if the function itself contains print(__name__) and I call the function, it returns __main__(yes, __main__ itself, not the string "__main__") (which is the calling function).

    >
    >
    >
    > That's because __name__ looks for that attribute on the module (aka
    >
    > "global variable"), not the function. When you run your Python script
    >
    > as an application, the module is called __main__.
    >
    >
    >
    > ChrisA


    Ok, that sheds some light on why it acts like that, but how can i use it the way I want (which i already told)?
     
    Abhas Bhattacharya, Dec 27, 2012
    #10
  11. On Thu, Dec 27, 2012 at 6:46 PM, Abhas Bhattacharya
    <> wrote:
    > [ a whole lot of double-spaced quoted text - please trim it ]
    > If i call one() and two() respectively, i would like to see "one" and "two".


    That completely goes against your idea of knowing at compile-time,
    because the name "two" isn't anywhere around at that time.

    There's no way to know what name was used to look something up. It
    might not even have a name - the called function could well have been
    returned from another function:

    # foo.py
    def indirection():
    return lambda: print

    # bar.py
    import foo
    foo.indirection()()("Hello, world!")

    What are the names of all the functions called here?

    ChrisA
     
    Chris Angelico, Dec 27, 2012
    #11
  12. On Thursday, 27 December 2012 13:22:45 UTC+5:30, Chris Angelico wrote:
    > On Thu, Dec 27, 2012 at 6:46 PM, Abhas Bhattacharya
    >
    > <> wrote:
    >
    > > [ a whole lot of double-spaced quoted text - please trim it ]

    >
    > > If i call one() and two() respectively, i would like to see "one" and "two".

    >
    >
    >
    > That completely goes against your idea of knowing at compile-time,
    >
    > because the name "two" isn't anywhere around at that time.
    >
    >
    >
    > There's no way to know what name was used to look something up. It
    >
    > might not even have a name - the called function could well have been
    >
    > returned from another function:
    >
    >
    >
    > # foo.py
    >
    > def indirection():
    >
    > return lambda: print
    >
    >
    >
    > # bar.py
    >
    > import foo
    >
    > foo.indirection()()("Hello, world!")
    >
    >
    >
    > What are the names of all the functions called here?
    >
    >
    >
    > ChrisA


    Yes, I get it that it may not be possible in complex cases (mostly using lambda functions). But in the simple case I mentioned, is it possible?
     
    Abhas Bhattacharya, Dec 27, 2012
    #12
  13. On Thursday, 27 December 2012 13:22:45 UTC+5:30, Chris Angelico wrote:
    > On Thu, Dec 27, 2012 at 6:46 PM, Abhas Bhattacharya
    >
    > <> wrote:
    >
    > > [ a whole lot of double-spaced quoted text - please trim it ]

    >
    > > If i call one() and two() respectively, i would like to see "one" and "two".

    >
    >
    >
    > That completely goes against your idea of knowing at compile-time,
    >
    > because the name "two" isn't anywhere around at that time.
    >
    >
    >
    > There's no way to know what name was used to look something up. It
    >
    > might not even have a name - the called function could well have been
    >
    > returned from another function:
    >
    >
    >
    > # foo.py
    >
    > def indirection():
    >
    > return lambda: print
    >
    >
    >
    > # bar.py
    >
    > import foo
    >
    > foo.indirection()()("Hello, world!")
    >
    >
    >
    > What are the names of all the functions called here?
    >
    >
    >
    > ChrisA


    Yes, I get it that it may not be possible in complex cases (mostly using lambda functions). But in the simple case I mentioned, is it possible?
     
    Abhas Bhattacharya, Dec 27, 2012
    #13
  14. On 12/27/2012 02:45 AM, Abhas Bhattacharya wrote:
    > On Thursday, 27 December 2012 10:22:15 UTC+5:30, Tim Roberts wrote:
    >> Abhas Bhattacharya <> wrote:
    >>
    >>> While I am defining a function, how can I access the name (separately as
    >>> string as well as object) of the function without explicitly naming
    >>> it(hard-coding the name)?
    >>> For eg. I am writing like:
    >>> def abc():
    >>> #how do i access the function abc here without hard-coding the name?

    >>
    >>
    >> Why? Of what value would that be?
    >>
    >>
    >>
    >> Note that I'm not merely being obstructionist here. What you're asking
    >>
    >> here is not something that a Python programmer would normally ask. The
    >>
    >> compiled code in a function, for example, exists as an object without a
    >>
    >> name. That unnamed object can be bound to one or more function names, but
    >>
    >> the code doesn't know that. Example:
    >>
    >>
    >>
    >> def one():
    >>
    >> print( "Here's one" )
    >>
    >>
    >>
    >> two = one
    >>
    >>
    >>
    >> That creates one function object, bound to two names. What name would you
    >>
    >> expect to grab inside the function?
    >>
    >>
    >>
    >> Even more obscure:
    >>
    >>
    >>
    >> two = lamba : "one"
    >>
    >> one = two
    >>
    >>
    >>
    >> Which one of these is the "name" of the function?
    >>
    >> --
    >>
    >> Tim Roberts,
    >>
    >> Providenza & Boekelheide, Inc.

    > It is of quite value to me.
    > Because I have this situation:
    > I have used a dictionary with "function_name":value pair in the top of the code. Now when some function is called, I need to print the value assigned to its name in the dictionary (the functions are defined after the dictionary). Now there is only one bad way-around for me: I need to hard-code the name in the function like this:
    > def function_name():
    > print(dict_name.get("function_name"))
    > but ofcourse it is a bad thing to do because I have a lot of this type of functions. It would be better if I can can use the same code for all of them, because they are all essentially doing the same thing.
    >
    > Now, for your questions:
    > If i call one() and two() respectively, i would like to see "one" and "two".
    > I dont have much knowledge of lambda functions, neither am i going to use them, so that's something I cant answer.


    How about defining a function that prints value and then calls a function?

    def call(func_name):
    print(mydict[func_name])
    globals()[func_name]()


    You could also define a custom class that does the same thing on attribute
    lookup and do something like Call.func_name() .

    -m

    --
    Lark's Tongue Guide to Python: http://lightbird.net/larks/
     
    Mitya Sirenef, Dec 27, 2012
    #14
  15. On Thursday, 27 December 2012 13:33:34 UTC+5:30, Mitya Sirenef wrote:
    >
    > How about defining a function that prints value and then calls a function?
    >
    >
    >
    > def call(func_name):
    >
    > print(mydict[func_name])
    >
    > globals()[func_name]()
    >
    >
    >
    >
    >
    > You could also define a custom class that does the same thing on attribute
    >
    > lookup and do something like Call.func_name() .
    >
    >
    >
    > -m
    >
    >
    >
    > --
    >
    > Lark's Tongue Guide to Python: http://lightbird.net/larks/


    Can you explain me what this means?
    globals()[func_name]()
     
    Abhas Bhattacharya, Dec 27, 2012
    #15
  16. On Thursday, 27 December 2012 13:33:34 UTC+5:30, Mitya Sirenef wrote:
    >
    > How about defining a function that prints value and then calls a function?
    >
    >
    >
    > def call(func_name):
    >
    > print(mydict[func_name])
    >
    > globals()[func_name]()
    >
    >
    >
    >
    >
    > You could also define a custom class that does the same thing on attribute
    >
    > lookup and do something like Call.func_name() .
    >
    >
    >
    > -m
    >
    >
    >
    > --
    >
    > Lark's Tongue Guide to Python: http://lightbird.net/larks/


    Can you explain me what this means?
    globals()[func_name]()
     
    Abhas Bhattacharya, Dec 27, 2012
    #16
  17. On Thursday, 27 December 2012 13:56:24 UTC+5:30, Chris Rebert wrote:
    > On Dec 25, 2012 6:06 PM, "Abhas Bhattacharya" <> wrote:
    >
    > >

    >
    > > While I am defining a function, how can I access the name (separately as string as well as object) of the function without explicitly naming it(hard-coding the name)?

    >
    > > For eg. I am writing like:

    >
    > > def abc():

    >
    > >     #how do i access the function abc here without hard-coding the name?

    >
    > Not possible per se without resorting to sys._getframe() or similar hackery.
    >
    > A simple+elegant way to do this would require PEP 3130 (http://www.python..org/dev/peps/pep-3130/ ) or similar, but that particular proposal got rejected.


    Thanks for telling that. I thought that there is a direct way, and now you have confirmed that there isn't. So, as I can see, Mitya's code can be a perfect way-around, although it will require another function.
     
    Abhas Bhattacharya, Dec 27, 2012
    #17
  18. On Thursday, 27 December 2012 13:56:24 UTC+5:30, Chris Rebert wrote:
    > On Dec 25, 2012 6:06 PM, "Abhas Bhattacharya" <> wrote:
    >
    > >

    >
    > > While I am defining a function, how can I access the name (separately as string as well as object) of the function without explicitly naming it(hard-coding the name)?

    >
    > > For eg. I am writing like:

    >
    > > def abc():

    >
    > >     #how do i access the function abc here without hard-coding the name?

    >
    > Not possible per se without resorting to sys._getframe() or similar hackery.
    >
    > A simple+elegant way to do this would require PEP 3130 (http://www.python..org/dev/peps/pep-3130/ ) or similar, but that particular proposal got rejected.


    Thanks for telling that. I thought that there is a direct way, and now you have confirmed that there isn't. So, as I can see, Mitya's code can be a perfect way-around, although it will require another function.
     
    Abhas Bhattacharya, Dec 27, 2012
    #18
  19. Abhas Bhattacharya

    Chris Rebert Guest

    On Dec 26, 2012 11:55 PM, "Abhas Bhattacharya" <>
    wrote:
    >
    > On Thursday, 27 December 2012 10:22:15 UTC+5:30, Tim Roberts wrote:
    > > Abhas Bhattacharya <> wrote:
    > >

    [Oh god please stop/avoid using Google Groups with its godawful
    reply-quoting style that adds excessive blank lines]
    > > >While I am defining a function, how can I access the name (separately

    as
    > > >string as well as object) of the function without explicitly naming
    > > >it(hard-coding the name)?
    > > >For eg. I am writing like:

    > >
    > > >def abc():
    > > > #how do i access the function abc here without hard-coding the

    name?
    > >
    > > Why? Of what value would that be?

    <snip>
    > Because I have this situation:
    > I have used a dictionary with "function_name":value pair in the top of

    the code. Now when some function is called, I need to print the value
    assigned to its name in the dictionary (the functions are defined after the
    dictionary). Now there is only one bad way-around for me: I need to
    hard-code the name in the function like this:
    > def function_name():
    > print(dict_name.get("function_name"))
    > but ofcourse it is a bad thing to do because I have a lot of this type of

    functions. It would be better if I can can use the same code for all of
    them, because they are all essentially doing the same thing.

    I agree with the general outline of Mitya's suggestion, i.e. refactor the
    "print the associated value" step into a separate function, thus obviating
    the self-reference issue; it'd be bad to repeat that code in each function
    anyway.

    Anyhow, here's a simple variation that exploits decorators (because they're
    generally awesome & one of my favorite features):

    def printing_name_beforehand(func):
    def wrapper(*args, **kwargs):
    print(the_dict.get(func.__name__))
    return func(*args, **kwargs)
    return wrapper

    Usage:

    @printing_name_beforehand
    def some_func(...):
    # whatever

    (Forgive me if there are typos; composing this reply on a tablet is
    cumbersome.)
     
    Chris Rebert, Dec 27, 2012
    #19
  20. On 12/27/2012 03:26 AM, Abhas Bhattacharya wrote:
    > On Thursday, 27 December 2012 13:33:34 UTC+5:30, Mitya Sirenef wrote:
    >> How about defining a function that prints value and then calls a function?
    >>
    >>
    >>
    >> def call(func_name):
    >>
    >> print(mydict[func_name])
    >>
    >> globals()[func_name]()
    >>
    >>
    >>
    >>
    >>
    >> You could also define a custom class that does the same thing on attribute
    >>
    >> lookup and do something like Call.func_name() .
    >>
    >>
    >>
    >> -m
    >>
    >>
    >>
    >> --
    >>
    >> Lark's Tongue Guide to Python: http://lightbird.net/larks/

    > Can you explain me what this means?
    > globals()[func_name]()


    globals() is a globals dictionary that maps function
    names to function objects (along with other things),
    so we get the function object by name and then
    run it.

    -m

    --
    Lark's Tongue Guide to Python: http://lightbird.net/larks/
     
    Mitya Sirenef, Dec 27, 2012
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Boogie El Aceitoso

    Error while defining char array

    Boogie El Aceitoso, Dec 3, 2003, in forum: C++
    Replies:
    6
    Views:
    420
    Jumbo
    Dec 3, 2003
  2. johny smith
    Replies:
    8
    Views:
    450
    Peter Koch Larsen
    Jul 2, 2004
  3. Brian van den Broek

    broke IDLE while defining a key-binding scheme

    Brian van den Broek, Feb 5, 2005, in forum: Python
    Replies:
    0
    Views:
    358
    Brian van den Broek
    Feb 5, 2005
  4. lcaamano
    Replies:
    2
    Views:
    292
    lcaamano
    May 9, 2006
  5. Sur
    Replies:
    4
    Views:
    229
Loading...

Share This Page